ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
12
返回列表 发新帖
楼主: m_n_j001

Collection快吗?

[复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-21 08:17 | 显示全部楼层
香川群子 发表于 2013-11-20 23:49
是来源于这个帖子中
http://club.excelhome.net/thread-1032842-5-1.html

来源不重要,重要的是我错在哪儿?
还有就是,除了您上回帮我写的那个排列,狼版提供的排序,还有哪些应用示例可以体现出用集合的优势?

TA的精华主题

TA的得分主题

发表于 2013-11-21 09:07 | 显示全部楼层
Collection除了作为集合类对象,其他用处都很少,用它取不重复、排序都不是好办法。

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-21 10:34 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
是这样哈?那就不再纠结了{:soso_e182:}

TA的精华主题

TA的得分主题

发表于 2013-11-21 11:31 | 显示全部楼层
快慢都是针对特定操作而言的,各种数据结构有自己“擅长”和“不擅长”的操作,适用于不同的情形。
对于VB6的Collection来说,它本质上是一个双链表,具有快速的插入和删除,但是无法随机访问节点。也就是说,如果你想要直接访问链表的第100个节点,办不到,只能从第一个元素开始往后数,数到100就是第100个元素。这也就是用for + index“遍历”Collection越到后面越慢的原因。

另外,链表的快速插入和删除是建立在已经取得节点的前提上的,也就是不包括获取节点的开销。对大部分语言的大部分链表实现来说,这不是问题,因为它们都是直接与链表节点交互。

但是VB6为了使用方便简单,没有直接暴露节点给用户,而是使用位置索引或者key索引来间接访问节点。因此就涉及到一个通过索引查找节点的过程。

其中,使用位置索引查找节点就如同上文描述的那样,从头开始线性查找,速度慢。所以Collection任何使用位置索引的操作都是相当慢的。比如,
要Remove(10000)就要先从头数到第10000个节点,然后才能删除那个节点。不过一旦找到第10000个节点,之后的实际删除操作就非常快了。
要Add("sss",before:=3800)就要先找到第3800个节点,然后才能在前面插入新节点。不过一旦找到第3800个节点,之后的实际插入操作也非常快。

另外一种方法是使用key索引来访问节点。使用这种方法时,每个节点都被关联了一个字符串类型的key,Collection内部维护一个hash表来迅速地通过key查找对应的节点。
比如,Remove("10000"),Collection会通过hash表直接定位到key为"10000"的节点,然后删除它。


总的来说,
1.Collection本质是一个链表,因此适合用于维护一组需要频繁插入删除的数据。而在访问节点的时候,应该首选使用key索引访问。
2.由于Collection内部维护了一个Key的Hash表,所以在没有Dictionary的时候,可以当做Hash表来使用。(Dictionary加入VB的时间比Collection晚,而且是vbs的组件,需要独立的dll)

至于你的代码,
你的三段代码根本就不等价,执行的操作都不同,没有可比性。比如你的数组没有进行实质上的“删除”操作,而Collection进行了实际的删除。如果真的对数组进行删除操作的话,它的速度也会大幅下降。这也正是洗牌算法的优点,避免了实际的删除操作。
真的要拼删除速度的话,链表是远胜于数组的。

评分

3

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-21 15:37 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
非常感谢14楼的达人!
最希望看到这样的的回复,有其然更有其所以然{:soso_e179:}

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-11-22 11:01 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
学习记录:利用集合进行排序,不稳定排序
Sub test0()    '生成测试数据
Dim ar(1 To 20000, 1 To 1)
For i = 1 To 20000
    t = Int(16384 * Rnd() + 1)
    ar(i, 1) = Split(Cells(t).Address, "$")(1)
Next
[a1:a20000] = ar
End Sub
Sub test1()   '利用集合排序,不稳定。计时不含读、写单元格时间
Dim c As New Collection, ar()
ar = [a1:a20000].Value
ttt = Timer
For i = 1 To 20000
    For Each t In c
        If t >= ar(i, 1) Then Exit For
    Next
    If t = Empty Then
       c.Add ar(i, 1), "|" & ar(i, 1)
    Else
       If t <> ar(i, 1) Then
          c.Add ar(i, 1), "|" & ar(i, 1), before:="|" & t
       Else
          i2 = i2% + 1
          c.Add ar(i, 1), "|" & i2 & ar(i, 1), after:="|" & ar(i, 1)
       End If
    End If
Next
i = 0
For Each t In c
   i = i + 1
   ar(i, 1) = t
Next
[b1] = Timer - ttt
[c1:c20000] = ar
End Sub

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-25 05:58 , Processed in 0.034062 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表