对数据一次性载入的进一步讨论

本文探讨了内存占用的评估方法及优化策略,包括不同数据结构的选择、内存泄露的原因及其解决方案,并对比了集合与数组的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

版权声明:可以任意转载,转载时请务必以超链接形式标明如下文章原始出处和作者信息及本声明

作者:xixi

出处:http://blog.youkuaiyun.com/slowgrace/archive/2009/04/20/4095485.aspx

本文来自此帖的讨论,感谢Tiger_Zhao的指点。

1、关于内存占用的探讨

西西:另外,对数据量我没什么概念。这个数据,尤其是基础节点是日积月累的。可能几十万个节点,都一次性地读到内存里(不光是节点关系,还包括各节点的具体信息),一直占用内存?你确定这样做没问题么?我觉得,至少的话,折中一下。如果树表的内容一次性全Load到内存里,细节表里的内容还是随用随取吧,毕竟细节表的内容我并不全用于树控件的显示的,大部分是用于细节子窗体的显示的。而且的话,因为我随用随取,用户一次要取的内容很有限(就1个节点:细节子窗体一次只显示一个当前节点的内容;最多的话,也就在listview里同时拖拽多个节点,不过这时候也用不大到细节了,因为Listview显示的时候,细节子窗体是不可见的),这样即使数据库存取慢,也慢不到哪儿去吧?

Zhao:数据是否要全体载入,要看运行环境和数据量。这里数据量不是简单的记录数,最直观的方法是按字段最大长度填充一个集合类,看内存增长多少。TreeView 要展开时动态添加,是因为每个节点的添加都要耗用一定的时间,乘上记录数就很可观了。而纯数据结构的集合类,填充速度基本与内存耗用(记录数×记录数据量)有关,而且与数据库操作相比就是小头。在物理内存足够的情况下尽量全部载入。举个例子,在一般计算机只有 128M 甚至更低内存的时候,程序一次操作10^3的记录是很慢的。但是 IBM 在演示 DB2 数据库时是同时操作10^6的记录,眨眼间完成,因为:他们有 4GB 内存的服务器,在内存中开了临时表空间,然后通过临时表操作数据。——这就是运行环境的影响。

2、关于内存占用的试验

我实际试了一下,发现我原来对内存占用的担心有点多余。具体做法是:

(1)做个类,和字段一一对应。然后用一个for循环,new数万个实例,这样去看内存增大多少。

(2)字符串要按照最大字段长度赋值,或者直接在类定义写private m_strName as string * 255。不过,这两种有些差别,定长字符串就不储存字符串指针,少用了4个字节,可用如下代码验证:

(3)我的实际测试代码如下,10万个记录,内存增长约0.06g:

(4)

西西:有没有什么办法测试我new的对象实例的实际大小,我现在这么定义的:

zhao:对象除了本身的数据,还有 VTable指针、引用计数等,求内存增长的平均数就可以了。

3、内存数据的释放

西西:不过,令我不解的是,创建10万个对象很快,几乎1、2秒钟就完成,而释放对象很慢,大约需要1、2分钟,这还是系统自动释放的速度。如果我像下面这样显式地释放,会需要更多时间:

而且释放的时候CPU的占用也上升得很快,我原来CPU大约是15%多,释放过程中峰值达到几乎60%。所以,这个程序将来的效果是启动很快,关闭会很慢。

zhao:COM 对象有引用计数,Set ... = Nothing 其实是调用 IUnknown::Release,由它决定是否要真正释放。所以对象创建比释放慢很多。针对这种情况,在《高级 Visual Basic 编程》(Advanced Visual Basic) 中用轻量对象来提升性能。不过这里不用这么复杂,CDetail 改用结构,CDetailList 用数组存放明细。差别就是必须整个结构进行存取而不能单独变更某个属性,不过正好方便实现消息通知(更新只有一个入口,更容易控制)。

4、关于集合和数组的讨论

西西:我感觉用结构数组的话其实只是把用类最后那一下慢,分散到每次操作中去了。因为用结构数组每次我要找个detailid都要遍历数组找,也挺花时间的。另外,为什么用数组不用集合呢?用集合的话我要定位到特定detail,只要用key就可以直接引用。用数组的话,还得找一番。是吧?

zhao:工程内定义的结构无法赋给 Variant 变量,也就无法加到集合中。解决方法:
A)在 tlb 中定义结构,就可以加到集合中。
B)用数组存放结构,将 Key-Index 对应关系加到集合中,也能快速定位。
C)用有序的数组存放结构,直接用二分法查找。 

更多树类文章

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值