在VB6中破坏树结构的最快方法
我有一些 VB6 代码,它创建了一个中等大小的树结构(几千个节点)。除非销毁对树的最后一个引用,否则性能是足够的。有时这可能需要一秒钟或更长时间。我尝试在删除节点本身之前杀死每个节点内的所有内部引用,但这似乎没有帮助。是否有一些技巧可以加快 vb6 使用其引用计数器所做的任何事情?性能似乎有一个重要的 N^2 方面。
顺便说一句,我知道 VB6 已经过时了,但有人抱怨我很久以前写的这段代码,但仍在使用。
顺便说一句,树不是二叉树,而是允许每个节点有任意数量的子节点,保存在集合中并按名称访问(因此一个节点可能是 TheTree!This!That!TheOtherThing!Whatever,又名 TheTree( “这个”)(“那个”)(“其他事情”)(“无论如何”))。
I have some code in VB6 which creates a moderately-large tree structure (a few thousand nodes). Performance is adequate except when destroying the last reference to a tree. That can sometimes take a second or more. I've tried killing all the internal references within each node before deleting the node itself, but that doesn't seem to help. Is there some trick to speed up whatever vb6 is doing with its reference counters? There seems to be a significant N^2 aspect to the performance.
Incidentally, I know VB6 is obsolescent, but I have someone complaining about this code which I wrote quite some time ago but which is still in use.
BTW, the tree is not a binary tree, but instead allows each node to have an arbitrary number of children, held in a Collection and accessed by name (so one node might be TheTree!This!That!TheOtherThing!Whatever, aka TheTree("This")("That")("TheOtherThing")("Whatever")).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
VB6 集合对象因释放其内容缓慢而臭名昭著,尤其是当存在大量包含的引用时。
您可以尝试替换集合,例如这个。还有许多其他 VB6 的替代集合,本质上应该是兼容的。
您可能还想阅读 Bruce Mckinney 对集合对象的观点。
编辑:更多布鲁斯·麦金尼信息此处
VB6 collection objects are notorious for being slow to release their contents, esp when there's a lot of contained references.
You might try a replacement collection, like this. There's a number of other replacement Collections for VB6 that should be essentially drop in compatible.
You might also want to read up on Bruce Mckinney's take on the collection object.
EDIT: More Bruce McKinney info here
我讨厌传递坏消息,但我怀疑您是否能够减少终止对象树所需的时间。大约 10 年前,我在 VB6 中共同开发了 SQL Accord——一个进行数据库比较的应用程序。因此,正如您可以想象的那样,您在内存中保存了数千个对象(例如表/视图/存储过程/等定义)以便能够快速比较它们。
由于OP提出的问题,将这些物品收藏起来的最初设计落到了地板上。罪魁祸首是 COM 垃圾收集方案 - 当您将对象设置为 Nothing/Null 时,它需要进行清理,然后很可能需要对内存空间进行碎片整理 - 这需要时间。
我的解决方案(当时很痛苦)是将所有对象转换为 TYPE 结构并将集合转换为类型数组。然后我构建了管理器对象来处理数组/类型/等...
尽管代码在您查看时有异味 - 我从中获得了 10 倍的性能提升。为什么?因为 TYPE 结构位于堆栈上,而对象位于堆上,在堆上处理它们的成本要高得多。
I hate to be the bearer of bad news, but I doubt you'll be able to reduce the amount of time that it takes to terminate the object tree. 10 years ago or so I co-developed SQL Accord in VB6 -- an application that did database comparisons. So as you can imagine you are holding thousands of objects in memory (e.g. table/view/sproc/etc definitions) to be able to quickly compare them.
The initial design of holding these objects in collections fell on the floor due to the issues that the OP brought up. The culprit is the COM garbage collection scheme - it needs to clean up the moment you set the object to Nothing/Null and then most likely it needs to defrag the memory space - that takes time.
My solution (painful at the time) was to convert all objects into TYPE structures and convert collections into arrays of types. Then I built manager objects to deal with the arrays/types/etc...
Even though the code smells when you look at it - I got a 10x performance increase out of it. Why? Because TYPE structures go on the stack, while objects go on the heap, where it is much more expensive to dispose of them.
Curland 的 Advanced Visual Basic 解释了如何创建轻量级 COM 对象以及如何在大型对象系统中组织这些对象的实例使用自定义内存管理器。好处基本上是您可以分配一大块(或几个但不是很多)内存来存储可以一次性释放的所有实例。这将拆卸时间减少到零。
轻量级对象是封装在 COM 接口中的结构(VB6 中的类型),因此看起来像常规 COM 对象。 UDT 数组的分配和销毁速度非常快,因为它们占用单个内存块。
Curland's Advanced Visual Basic explains how to create lightweight COM objects and how to organize instances of these in large systems of objects that use custom memory manager. The benefit is basicly that you can allocate a large single (or several but not many) chunk of memory to store all the instances that can be released in one go. This reduces tear down time to zero.
Lightweight objects are structs (
Type
s in VB6) wrapped in COM interfaces so to look like regular COM objects. Arrays of UDTs are allocated and destroyed very fast as these occupy a single chunk of memory.