ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[讨论] VBA数组运算速度 - ReDim 和 ReDim Preserve 速度对比

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2013-5-6 22:06 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
香川群子 发表于 2013-5-5 21:46
使用VBA内存数组时,读、写入数组时首先需要检索行、列位置。

而数组中定位置也并非人类脑子中想一想那么 ...
tmp = arr(20,1) 这么简单一句要求,
但电脑计算机并不能直接定位到第20行、第1列。
而是要先计算该数组的一半 = 50,然后发现 20<50
于是接着计算50的一半 = 25,然后发现 20<25
于是接着计算25的一半 = 12,然后发现 20>12
于是接着计算12 -25 的一半 = 18,然后发现 20>18
…………
<50 →<25 →>12 →>18 →<21 →>19 →=20

这样子经过6步计算最后才定位到arr(20,1) 的。


论坛不允许纯表情符号~但我仍然@_@

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 22:13 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
香川群子 发表于 2013-5-6 21:51
折中的方法是:

1. 直接定义一个适当大小的数组……

群子老师:
    你的意思是不是循环一次就判断一次 k mod kc = 0 ?

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 22:16 | 显示全部楼层
本帖最后由 jinbo3535 于 2013-5-6 22:20 编辑
灰袍法师 发表于 2013-5-6 21:47
因此,你当然可以理解下述结果:
一维数组显然要比二维数组速度更快一些。因为只需确定1个列位置就够了 ...


灰袍老师:
    把 dim arr(1 to 100, 1 to 4) 改为 dim arr(1 to 400),这句看得懂,把2维改1维!
    然后自己的代码把所有的 arr(m, n) 改为  arr(  4*(m-1) + n ),这句看不太懂?

    还有100MB 的数组、10MB 的数组 要怎么算出来?

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 22:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
香川群子 发表于 2013-5-6 21:40
借助辅助单元格作为临时数据的储存这个方法非常地不好,绝对不可以哦!

…………

明白了,把结果一次放入单元格和循环、多次放入单元格的速度差别那么大!

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 23:04 | 显示全部楼层
香川群子 发表于 2013-5-6 21:40
借助辅助单元格作为临时数据的储存这个方法非常地不好,绝对不可以哦!

…………

群子老师:
         再请教您一个问题,数组赋值给单元格的大小,速度上会差很多吗?
         比如:数组(1 To 1000,1 to 1500)、数组(1 To 100,1 To 100)赋值给对应大小的单元格,在速度上会差很多吗?

TA的精华主题

TA的得分主题

发表于 2013-5-7 02:08 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
jinbo3535 发表于 2013-5-6 22:16
灰袍老师:
    把 dim arr(1 to 100, 1 to 4) 改为 dim arr(1 to 400),这句看得懂,把2维改1维!
  ...

arr(m, n) 改为  arr(  4*(m-1) + n ),这句看不太懂?
===================================
就是说,原本是 arr(1,3) 访问二维数组,第一行第3列的元素
改为一维数组以后,该元素的位置就变成 arr(3) ,第1行第3个元素

同理,原本是  arr( 10,2) ,现在就是 arr( 4*(10-1) +2 = arr(38)

其实就是计算 改为一维数组以后,对应的新数组位置而已。

100 MB 的数组要自己算了,如果每个数组元素占 4 字节
那么 dim arr(1 to 25 * 1048576) 就会声明一个刚好 100MB 的数组

不过实际上也不需要这么精密
直接 dim arr( 1 to  10万),然后
lastpos = ubound(arr)
每当数组元素增加到 lastpos 的时候

redim preserve arr (1 to lastpos + 10万 )
lastpos = ubound(arr)
即可。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2013-5-7 08:55 | 显示全部楼层
灰袍法师 发表于 2013-5-6 21:09
只有在程序中查找数组元素才有可能是这样的二分法查找

如果是计算机内部寻址

但是对于减少好象是不需要拷贝的:
  1. Sub test()
  2. n = 99999
  3. ReDim a(n)
  4. t = Timer
  5. For i = n To 1 Step -1
  6.   ReDim Preserve a(i)
  7. Next
  8. t1 = Timer - t

  9. ReDim b(n)
  10. t = Timer
  11. For i = 1 To n
  12.   ReDim Preserve a(i)
  13. Next
  14. t2 = Timer - t
  15. MsgBox t1 & Chr(10) & t2
  16. End Sub
复制代码
所以,我处理这种问题一般用两种方法:定义更大的数组,视情况看需不需要redim preserve 一次要;第二是先计算数组大小,再定义数组。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-7 10:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
灰袍法师 发表于 2013-5-7 02:08
arr(m, n) 改为  arr(  4*(m-1) + n ),这句看不太懂?
===================================
就是说, ...

谢谢老师···

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-7 10:32 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
Zamyi 发表于 2013-5-7 08:55
但是对于减少好象是不需要拷贝的:所以,我处理这种问题一般用两种方法:定义更大的数组,视情况看需不需 ...

各位老师的意见统一,还是尽量不要用preserve关键字···
学习了,谢谢···

TA的精华主题

TA的得分主题

发表于 2014-2-12 20:09 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-28 04:15 , Processed in 0.039464 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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