ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] 数据类型与效率的问题(无解)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2010-11-26 11:57 | 显示全部楼层
Bi 和 B2 的比较是因为 字典key值是 String如果赋值是数据类型,内部会隐式转换增加了时间,而且常常会出错如果先转换成会比 B2 快因为 B2 有一个连接字符串的运算。

请测试:
  1. Sub TestB1()
  2. N = 10000
  3. Dim d
  4. Set d = CreateObject("scripting.dictionary")

  5. t = Timer
  6. For i = 10000001 To 10000000 + N
  7.   d(CStr(i)) = ""
  8.   Next
  9. t1 = Timer - t
  10. Set d = Nothing
  11. [e1] = t1 '0.04秒
  12. End Sub

  13. Sub TestB2()
  14. N = 10000
  15. Dim d
  16. Dim s As String
  17. Dim t2
  18. Set d = CreateObject("scripting.dictionary")

  19. t = Timer
  20. For i = 10000001 To 10000000 + N
  21.   s = "" & i
  22.   d(s) = ""
  23.   Next
  24. t2 = Timer - t
  25. Set d = Nothing
  26. [e2] = t2  '0.06秒
  27. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2010-11-26 12:22 | 显示全部楼层

回复 11楼 lipton 的帖子

恩,我曾经也是这样想.....
但,我昨天调试的时候
Sub TestB1()
n = 100000
Dim d
Set d = CreateObject("scripting.dictionary")
t = Timer
For i = 1 To n
  d(i) = ""
  Next
t1 = Timer - t
Set d = Nothing
[e1] = t1 '0.26
End Sub

Sub TestB2()
n = 100000
Dim d
Dim t2
Set d = CreateObject("scripting.dictionary")
t = Timer
For i = 1 To n
  d(CStr(i)) = ""
  Next
t2 = Timer - t
Set d = Nothing
[e2] = t2  '0.52
End Sub
我又迷惑了..

TA的精华主题

TA的得分主题

发表于 2010-11-26 12:34 | 显示全部楼层
原帖由 terqm 于 2010-11-26 12:22 发表
恩,我曾经也是这样想.....
但,我昨天调试的时候
Sub TestB1()
n = 100000
Dim d
Set d = CreateObject("scripting.dictionary")
t = Timer
For i = 1 To n
  d(i) = ""
  Next
t1 = Timer - t
Set d = No ...



确实是这样,会不会是隐式转换是逐个字符校验所以字符段的时候快,字符长了就慢,等待老师解惑。

TA的精华主题

TA的得分主题

 楼主| 发表于 2010-11-26 12:51 | 显示全部楼层
原帖由 lipton 于 2010-11-26 11:57 发表
Bi 和 B2 的比较是因为 字典key值是 String如果赋值是数据类型,内部会隐式转换增加了时间,而且常常会出错如果先转换成会比 B2 快因为 B2 有一个连接字符串的运算。

请测试:Sub TestB1()
N = 10000
Dim d
Se ...

事实上,是为了让人产生错觉才用:s=""& i /d(s)="",实际中用d("" &i) = "",这和d(CStr(i)) = ""差别并不大。

TA的精华主题

TA的得分主题

发表于 2010-11-26 13:08 | 显示全部楼层
看来是和字符长度有关,两段代码各少一零,速度就一样了

Sub TestB1()
N = 10000
Dim d
Set d = CreateObject("scripting.dictionary")

t = Timer
For i = 1000001 To 1000000 + N
  d(i) = ""
  Next
t1 = Timer - t
Set d = Nothing
[e1] = t1 '0.04秒
End Sub

Sub TestB2()
N = 10000
Dim d
Set d = CreateObject("scripting.dictionary")

t = Timer
For i = 1000001 To 1000000 + N
  d("" & i) = ""
  Next
t1 = Timer - t
Set d = Nothing
[e2] = t1 '0.04秒
End Sub

TA的精华主题

TA的得分主题

发表于 2010-11-26 16:45 | 显示全部楼层
看来是和字符长度有关,两段代码各少一零,速度就一样了
...


啊,终于有人愿意回到我前面的话题了。

TA的精华主题

TA的得分主题

发表于 2010-11-26 17:19 | 显示全部楼层
若然说是和字符长度有关....
我倒觉得...........和电脑的配置有关呢.

TA的精华主题

TA的得分主题

发表于 2010-11-26 19:46 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
不同长度的长整型对速度的影响,如果先行转换String,则速度平均。
  1. Sub test()

  2. Dim i As Long, j As Long, h As Long
  3. Dim N As Long, N1 As Long
  4. Dim t
  5. Dim d  As New Dictionary
  6. Dim d1 As New Dictionary

  7. h = 1
  8. N = 11
  9. N1 = 11
  10. 'Set d = CreateObject("scripting.dictionary")
  11. 'Set d1 = CreateObject("scripting.dictionary")

  12. Do
  13.     t = Timer
  14.     N = (N * 10) - 9
  15.     For i = N To N + 10000
  16.       d(i) = ""
  17.     Next i
  18.     t = Timer - t
  19.     d.RemoveAll
  20.     Sheet1.Cells(h, 1) = t
  21.    
  22.     t = Timer
  23.     N1 = (N1 * 10) - 9
  24.     For i = N1 To N1 + 10000
  25.       d1(CStr(i)) = ""
  26.     Next i
  27.     t = Timer - t
  28.     d1.RemoveAll
  29.     Sheet1.Cells(h, 2) = t
  30.     h = h + 1
  31. Loop While h <= 8

  32. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2010-11-27 05:46 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
试验了不同的数据类型

结论如下:

数值型的key,一旦接近1000万左右,大概是9990650以上吧

速度就会剧降

而字符型的key,不管如何如何都很快

这也证明了我在三楼的推测,应该是较大的数值在计算哈希值HashValue的时候,发生溢出错误所致

我怀疑VBA的字典,其HashValue是个32位整数,而计算过程使用质数211来做乘法,

然后对另一个接近2^31的大质数取模(比方说 2108027161)

所以最终导致稍微大于 2^31 / 211 的数值型key都会溢出,导致速度暴降

而字符型的key,应该使用了另一种计算HashValue的方法,不会溢出。

当然,在没看到VBA字典的源代码之前,这也只能是个猜测

[ 本帖最后由 灰袍法师 于 2010-11-27 06:45 编辑 ]

TA的精华主题

TA的得分主题

发表于 2010-11-27 12:17 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
没有更好的解释之前.....这应该是最好的解释了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2025-1-17 01:16 , Processed in 0.021966 second(s), 6 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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