• zList一个块状链表算法可以申请和释放同种对象指针,对于大数据量比直接new少需要差不多一半内存


    zList是一个C++的块状内存链表,特点:

    1、对于某种类别需要申请大量指针,zList是一个很好的帮手,它能比new少很多内存。

    2、它对内存进行整体管理,可以将数据和文件快速互操作

    3、和vector对象存储对比,vector存储的对象不能使用其指针,因为vector内容变化时vector存储对象的指针会变化

    4、zList也可以当做顺序的数组使用,它有自己的迭代器,可以遍历整个数组

    下面是申请5千万个RECT指针对比结果:

    zList申请五千万RECT指针内存占用:

    直接new五千万RECT指针内存占用:

    从对比看节省了724.6M的内存

    下面是zList实现代码:

      1 #include "stdafx.h"
      2 #include <set>
      3 #include <map>
      4 #include <string>
      5 #include <vector>
      6 #include <windows.h>
      7 using namespace std;
      8 
      9 template <class T>
     10 struct zElem
     11 {
     12     zElem() { memset(this, 0, sizeof(zElem)); }
     13     int has() //查找空闲的位置
     14     {
     15         return extra < 1024 ? extra : -1;
     16     }
     17     bool empty() { return 0 == size; };
     18     bool full() { return 1024 == size; };
     19     T *add(int i, const T &r)
     20     {
     21         bit[i] = 1;
     22         R[i] = r;
     23         size++;
     24         if (extra == i)//指向下一个位置
     25         {
     26             extra++;
     27             while (extra < 1024)
     28             {
     29                 if (bit[extra] == 0)break;
     30                 extra++;
     31             }
     32         }
     33         return R + i;
     34     }
     35     void remove(T *r)
     36     {
     37         int i = (int)(r - R);
     38         if (i >= 0 && i < 1024)
     39         {
     40             bit[i] = 0;
     41             if (extra > i)extra = (unsigned short)i;
     42             size--;
     43         }
     44     }
     45     bool in(T *r)
     46     {
     47         int i = (int)(r - R);
     48         return i >= 0 && i < 1024;
     49     }
     50     T* get(int i)
     51     {
     52         int ind = getInd(i);
     53         return ind == -1 ? NULL : R + ind;
     54     }
     55     int getInd(int i)
     56     {
     57         if (i >= 0 && i < extra)return i;
     58         int k = extra + 1, t = extra;
     59         while (k < 1024)
     60         {
     61             if (bit[k] != 0)
     62             {
     63                 if (t == i)return k;
     64                 t++;
     65             }
     66             k++;
     67         }
     68         return -1;
     69     }
     70     bool getInd(size_t &ind, size_t &off, size_t n)
     71     {
     72         if (ind + n < extra)
     73         {
     74             ind += n;
     75             off = ind;
     76             return true;
     77         }
     78         while (++ind < 1024)
     79         {
     80             if (bit[ind] != 0)
     81             {
     82                 n--;
     83                 off++;
     84                 if (n==0)return true;
     85             }
     86         }
     87         return false;
     88     }
     89     unsigned short extra;//指向当前空闲位置
     90     unsigned short size; //当前已有数据个数
     91     byte bit[1024];         //标记是否使用
     92     T R[1024];             //数据存储
     93 };
     94 template <class T>
     95 struct zList
     96 {
     97     struct iterator
     98     {
     99         T* operator *()
    100         {
    101             return p ? &p->head[ind]->R[zind] : NULL;
    102         }
    103         T* operator ->()
    104         {
    105             return p ? &p->head[ind]->R[zind] : NULL;
    106         }
    107         iterator& operator ++()
    108         {
    109             bool bend = true;
    110             if (p&&p->head.size() > ind)
    111             {
    112                 for (; ind < p->head.size(); ind++)
    113                 {
    114                     zElem<T>*a = p->head[ind];
    115                     if (zsize + 1 < a->size)
    116                     {
    117                         a->getInd(zind,zsize,1);
    118                         bend = false;
    119                         break;
    120                     }
    121                     zind = zsize = -1;
    122                 }
    123             }
    124             if (bend)
    125             {
    126                 ind = zsize = zind = 0; p = 0;
    127             }
    128             return (*this);
    129         }
    130         bool operator ==(const iterator &data)const
    131         {
    132             return ind == data.ind&&zind == data.zind&&zsize == data.zsize&&p == data.p;
    133         }
    134         bool operator !=(const iterator &data)const
    135         {
    136             return ind != data.ind||zind != data.zind||zsize != data.zsize||p != data.p;
    137         }
    138         explicit operator bool() const 
    139         {    
    140             return (!p);
    141         }
    142         size_t ind;            //p的位置
    143         size_t zind;        //zElem中的R位置
    144         size_t zsize;        //zElem中zind位置所在的次序
    145         zList *p;            //指向链表的指针
    146     };
    147     zList() :size(0),  extra(0) { }
    148     ~zList() 
    149     {
    150         for (auto &a: head)
    151         {
    152             delete a;
    153         }
    154     }
    155     T *add(const T &r)
    156     {
    157         zElem<T>* e;
    158         if (extra >= head.size())
    159         {
    160             e = new zElem<T>();
    161             head.push_back(e);
    162         }
    163         else
    164         {
    165             e = head[extra];
    166         }
    167         int i = e->has();
    168         T *R = e->add(i, r);
    169         size++;
    170         while (extra < head.size() && e->full())
    171         {
    172             e = head[extra];
    173             extra++;
    174         }
    175         return R;
    176     }
    177     void remove(T  *r)
    178     {
    179         if (r == NULL)return;
    180         zElem<T> *rem;
    181         size_t i = 0;
    182         for (; i < head.size(); i++)
    183         {
    184             rem = head[i];
    185             if (rem->in(r))
    186             {
    187                 size--;
    188                 rem->remove(r);
    189                 if (rem->empty())//删除当前节点
    190                 {
    191                     head.erase(head.begin() + i);
    192                     if (extra == i)
    193                     {
    194                         //往后查找空闲的位置
    195                         while (extra < head.size())
    196                         {
    197                             if (!head[extra]->full())break;
    198                             extra++;
    199                         }
    200                     }
    201                     delete rem;
    202                 }
    203                 else if(extra > i)
    204                 {
    205                     extra = i;
    206                 }
    207                 break;
    208             }
    209         }
    210     }
    211     T* get(int i)
    212     {
    213         for (auto &a : head)
    214         {
    215             if (i < a->size)
    216             {
    217                 return a->get(i);
    218             }
    219             i -= a->size;
    220         }
    221         return NULL;
    222     }
    223     void clear()
    224     {
    225         for (auto &a : head)
    226         {
    227             delete a;
    228         }
    229         head.clear();
    230         size = extra = 0;
    231     }
    232     iterator begin()
    233     {
    234         iterator it = { 0,0,0,NULL };
    235         if (head.size() > 0)
    236         {
    237             int i = 0;
    238             for (;it.ind < head.size(); it.ind++)
    239             {
    240                 zElem<T>*a = head[it.ind];
    241                 if (i < a->size)
    242                 {
    243                     it.p = this;
    244                     it.zind = a->getInd(i);
    245                     break;
    246                 }
    247                 i -= a->size;
    248             }
    249         }
    250         return it;
    251     }
    252     iterator end()
    253     {
    254         iterator it = {0,0,0,NULL};
    255         return it;
    256     }
    257     size_t size;                //个数
    258     vector<zElem<T>*> head;        //开头
    259     size_t extra;                //有空余位置的
    260 };
    View Code

    使用方法如下:

     1 int main()
     2 {
     3     zList<RECT> z;
     4     for (int i = 0; i < 50000000; i++)
     5     {
     6         //1、申请内存
     7         RECT r = { rand(), rand(), rand(), rand() };
     8         RECT *p = z.add(r);
     9         //2、可以对p进行使用...
    10         //3、释放内存
    11         z.remove(p);
    12     }
    13     getchar();
    14     return 0;
    15 }

    对zList进行元素遍历,迭代器方法:

    1 int t = 0;
    2 zList<RECT>::iterator its = z.begin();
    3 zList<RECT>::iterator ite = z.end();
    4 for (; its != ite; ++its)
    5 {
    6     RECT *p = *its;
    7     t = p->left;
    8 }

    对zList进行随机访问遍历,效率没有迭代器高:

    1 int t = 0;
    2 for (int i = 0; i < z.size; i++)
    3 {
    4     RECT *p = z.get(i);
    5     t = p->left;
    6 }
  • 相关阅读:
    hive:(group by, having;order by)的使用;group by+多个字段,以及wiki说的group by两种使用限制验证
    hive parition的使用,分dynamic和static两种
    saiku运行时报错max_length_for_sort_data 需要set higher
    kettle文件自动化部署(shell脚本执行):命令行参数传入
    saiku显示不出新的cube(加载的cube,saiku会保存到缓存中,不重新加载)
    黑暗网络购物让你隐形參与犯罪
    Swift开发实例:苹果Swift编程语言新手教程中文版+FlappyBird,2048游戏源代码
    自己定义控件-DragButton
    无锁编程实战演练
    使用hint优化Oracle的运行计划 以及 SQL Tune Advisor的使用
  • 原文地址:https://www.cnblogs.com/virtualNatural/p/10122901.html
Copyright © 2020-2023  润新知