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 };

使用方法如下:

 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 }

原文地址:https://www.cnblogs.com/virtualNatural/p/10122901.html

时间: 2024-10-10 20:48:06

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

从另一个角度看大数据量处理利器 布隆过滤器

思路:从简单的排序谈到BitMap算法,再谈到数据去重问题,谈到大数据量处理利器:布隆过滤器. 情景1:对无重复的数据进行排序 @给定数据(2,4,1,12,9,7,6)如何对它排序? 方法1:基本的排序方法包括冒泡,快排等. 方法2:使用BitMap算法 方法1就不介绍了,方法2中所谓的BitMap是一个位数组,跟平时使用的数组的唯一差别在于操作的是位. 首先是开辟2个字节大小的位数组,长度为16(该长度由上述数据中最大的数字12决定的)如图         然后,读取数据,2存放在位数组中下

解决WCF大数据量传输 ,System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接

开发中所用的数据需要通过WCF进行数据传输,结果就遇到了WCF大量传输问题 也就是提示System.Net.Sockets.SocketException: 远程主机强迫关闭了一个现有的连接 网上解决方案都是千篇一律互相转发的,并且没有明确的解决方案或者按照,各个博客中的解决方案都没能解决这个问题. 为此我整整浪费了一天时间用来解决这个问题,而且用了最笨的办法一点点的尝试网上所查到的方案.对于精研WCF来说的这可能是一个小问题,但是对于仅仅了解wcf,一知半解的会很困惑.将解决方案贴出来希望能帮

一个坑poi大数据量导入时的java.lang.IllegalStateException: Zip File is closed

本帖子没有答案,只是说一下坑,余下的自己决定. Caused by: java.lang.IllegalStateException: Zip File is closed at org.apache.poi3.openxml4j.util.ZipFileZipEntrySource.getEntries(ZipFileZipEntrySource.java:45) at org.apache.poi3.openxml4j.opc.ZipPackage.getPartsImpl(ZipPacka

[算法系列之十]大数据量处理利器:布隆过滤器

[引言] 在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中.比如在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断 它是否在已知的字典中):在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上:在网络爬虫里,一个网址是否被访问过等等.最直接的方法就是将集合中全部的元素存在计算机中,遇到一个新 元素时,将它和集合中的元素直接比较即可.一般来讲,计算机中的集合是用哈希表(hash table)来存储的.它的好处是快速准确,缺点是费存储空间.当集合比较小时,这个问题

mysql数据库索引查询一个优化大数据量的实例的分享

我们要访问的表是一个非常大的表,四千万条记录,id是主键,program_id上建了索引.执行一条SQL:select * from program_access_log where program_id between 1 and 4000 这条SQL非常慢.我们原以为处理记录太多的原因,所以加了id限制,一次只读五十万条记录select * from program_access_log where id between 1 and 500000 and program_id between

数据库水平分表(一个大数据量的表)

一.当一张表很大时,比如微信账号.facebook账号.QQ号.谷歌账号系统等,都是大数据量的一张表结构.那么必然需要进行拆分,即水平拆分. 二.表的水平拆分规则. 原文地址:https://www.cnblogs.com/igoodful/p/8974988.html

【POJ2887】【块状链表】Big String

Description You are given a string and supposed to do some string manipulations. Input The first line of the input contains the initial string. You can assume that it is non-empty and its length does not exceed 1,000,000. The second line contains the

大数据日知录:架构与算法

大数据丛书 大数据日知录:架构与算法(大数据领域专家力作,专注大数据架构和算法,全面梳理大数据相关技术) 张俊林 著   ISBN 978-7-121-24153-6 2014年9月出版 定价:69.00元 404页 16开 编辑推荐 这是一本心血之作,历时3年,质量上乘. 从架构与算法的角度,比较全面地分门别类梳理了大数据相关技术. 本书内容紧跟技术前沿,讲解深入浅出,适合大数据领域所有技术人员. 书中还列有作者优选的高质量文献,能为读者节省选择的时间,绝对值得一读. 内容提要 大数据是当前最

parquet文件格式——本质上是将多个rows作为一个chunk,同一个chunk里每一个单独的column使用列存储格式,这样获取某一row数据时候不需要跨机器获取

Parquet是Twitter贡献给开源社区的一个列数据存储格式,采用和Dremel相同的文件存储算法,支持树形结构存储和基于列的访问.Cloudera Impala也将使用Parquet作为底层的存储格式.在很多大数据的应用场景下面,比如电信行业,具有一定规则的数据,字段很多,但是每次查询仅仅针对其中少数的几个字段,这个时候列式存储是极佳的选择.优势: 使用列式存储,一列的值都是同质的,从而带来了更高的压缩比:对于在hadoop集群上的大数据量来说,使用parquet可以节省大量空间:可以提高