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 03:17 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
zhaogang1960 发表于 2013-5-6 01:30
不要听我的,我j追求的仅仅是用较少的知识尽可能的解决较多的实际问题,不太关心速度、效率和算法等

我 ...

我喜欢这句话。

TA的精华主题

TA的得分主题

发表于 2013-5-6 10:06 | 显示全部楼层
香川群子 发表于 2013-5-5 21:46
使用VBA内存数组时,读、写入数组时首先需要检索行、列位置。

而数组中定位置也并非人类脑子中想一想那么 ...

裙子姐姐的观点和俺不一致,请问有什么资料出处吗?俺也可以去学习学习
俺的浅见和学习以来一直的理解,如果是错误的还请教育俺:

vba 内存数组的访问,首先我们摒弃String 类型,因为字符串数组不是简单数据类型,而是封装了BSTR 结构,这个复杂类型我们暂时不讨论。

假设一个一维Integer 内存数组: Dim ar(100) as integer

假设要访问 ar(81) , 应该是计算机会首先找到该数组连续存储内存位置的首地址,即ar(0) 的地址,然后向后检索81 个位置,即该下标的偏移值。有点类似 基址+ 偏移地址的概念。我们知道vba 对于数组的访问都是Byref 也就是按址访问,那么是否应该理解为是通过指针的概念进行寻址求值访问的。

二维数组在内存中的存储也是和一维数组相同的,都是连续存储。并不是二维表的格式存储的,
比如定义二维数组 ar (1 to 2,1 to 2) 那么该数组在内存中应该是 ar(1,1), ar(1,2),ar(2,1),ar(2,2) 连续存储的就像一个一维数组一样。因此在访问时也是首先查找该二维数组的第一个元素的地址,然后进行寻址的。
请参考说明的附图:
array.JPG

点评

你说的对,实际上机器的寻址方式起码有十几种,看一眼我都会头晕。  发表于 2013-5-6 21:11

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 12:10 | 显示全部楼层
本帖最后由 jinbo3535 于 2013-5-6 12:23 编辑
Moneky 发表于 2013-5-6 02:21
我觉得这些就没多大讨论的必要吧,ReDim 和 ReDim Preserve 适用的场合不一样,何必讨论谈他们孰优孰劣,一 ...


Moneky 兄:
         我个人认为,redim preserve 与redim 就这两个关键字和数组里尽量不要用函数,对初学者来说,很重要!
原因:
       1.不是我喜欢追求速度!小数据无所谓追求速度,刷一下子结果就出来了!但有些过程中有像:数组(1 to 1000,1 to 1500),这样的数组用index循环个1000次试一试,你就知道了!这个我试过,在我的机子上,运行一个过程用index,运行了3分钟以上,我就停止后调试,发现循环才300次左右!同样的过程,没用这个函数,40多秒算完!

       2.过程中有函数,有算法,有其它未知的因素在影响速度!初学者一个刚刚接触新的知识,没经验!还是那句话,小数据无所谓追求速度!一个数组(1 to 1000,1 to 1500)这个可用redim preserve ,也可用redim !这里我举例用redim preserve 数组(1 to 1000,1 to X),再和index函数放到一个过程中,两个同样都影响速度!好了,有老师指导你函数影响速度,试一试!诶,真是呀,那就不用函数了,速度降到40多秒!没学过或者没经验,那你知道redim preserve 也会影响速度吗?用redim 那个过程那个过程还可以从40多秒又降到7秒多

       3.同样那个过程,循环计算一个结果出来,循环赋值给单元格,3分钟运行不完,多花了2分钟多!结果放到一个数组,再把数组一次性放到单元格里,用不了多少时间!

       在那么多的数组资料里都是入门的!
       有说,preserve会影响速度吗?
       有说,数组里不要用函数(比如数组里循环累加要比sum要快吗)?
       有说,单元格不要一个一个赋值,要一次性赋值比较快吗?
       有说,嵌套数组的运用实例:嵌套数组很好用,运算用 嵌套数组(N)(X,Y) 放数据方便;拿数据时可以选择 嵌套数组(N) 也方便吗?
       有说,不在数组里用函数,那其它一些统计算法,怎么处理吗(如找最大值,平均值之类)?

        我网上找了很多资料,几乎没见到说这些的;或者,有谁把这个功能强大,运算速度这么快的VBA内存数组的深入一点的运用和经验总一下的吗?当然,也许有,反正我是没找到!这些是我一个初学者的经历!假设,我刚提的那个过程,不注意上面那些,我猜10分钟1000次都循环不完!讨论这些,懂的人是没什么,重点是为了让不知道的人知道!希望,前辈们要好经验和教材能放上来,让我们这些初学者大有口福!这只是我个人看法。如果,前辈们有其它看法,也请指导一下!谢谢···

TA的精华主题

TA的得分主题

发表于 2013-5-6 15:22 | 显示全部楼层
本帖最后由 Moneky 于 2013-5-6 15:45 编辑
jinbo3535 发表于 2013-5-6 12:10
Moneky 兄:
         我个人认为,redim preserve 与redim 就这两个关键字和数组里尽量不要用函数,对 ...

我在前面回复中的“这些讨论”是指对redim 和 redim preserve 的速度讨论。redim 和 redim preserve的功能本身就不一样,各自适用不同的情况,到底适用哪些情况,看看他们的功能就知道了。我那里回复的另一个意思是没有必要用非黑即白的观点来看待某些东西,这个世界不是非黑即白,还有灰。所以,我认为对他俩的速度讨论是个美丽的伪命题。

对于你的“在数组中不要用函数”的说法,不在本帖的预设主题之中吧。(另外一个小细节, 数组里不要用函数——这句话有问题,猜想你表达的意思可能是:用了数组,就最好不同时调用工作表函数,而是直接对数组处理,实现那些工作表函数的功能)

下面这些话中的一些问题中,其实也是有相关资料提到过,可能不好找而已。
【在那么多的数组资料里,都是入门的!
       有说,preserve会影响速度吗?——我认为是个伪命题
       有说,数组里不要用函数(比如数组里循环累加要比sum要快吗)?——描述不清
       有说,单元格不要一个一个赋值,要一次性赋值比较快吗?——论坛上的大侠们早年就发过这类信息
       有说,嵌套数组的运用实例:嵌套数组很好用,运算用 嵌套数组(N)(X,Y) 放数据方便;拿数据时可以选择 嵌套数组(N) 也方便吗?——这个少见过,和3维数组一样看起来
       有说,不在数组里用函数,那其它一些统计算法,怎么处理吗(如找最大值,平均值之类)?——这是程序算法问题了

这些回复,没有冒犯你的意思,相反对你的研究态度和用心回复很是佩服。

编辑一下,提个小建议,少用感叹号——句号比感叹号更容易打哦,可以打字更快一点,因为句号只需要按一个键,而感叹号要按两个键,当然不是说句号就比感叹号好,因为在表示一些强烈语气的时候,只有感叹号更能表达。

TA的精华主题

TA的得分主题

发表于 2013-5-6 15:33 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
我认同Moneky的说法,了解了各自的用法,在实际应用中选择性使用就好了

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 17:33 | 显示全部楼层
Moneky 发表于 2013-5-6 15:22
我在前面回复中的“这些讨论”是指对redim 和 redim preserve 的速度讨论。redim 和 redim preserve的功能 ...

呵呵,可能命题有点问题。用"关于VBA数组运算速度"这个可能更好一点。算了,我只是一个初学者。其实,发这个贴子无非就是想收集一些和VBA数组有关深入一点点的知识,供我们这些初学者学习。

TA的精华主题

TA的得分主题

发表于 2013-5-6 17:37 | 显示全部楼层
本帖最后由 zhaogang1960 于 2013-5-6 17:40 编辑
jinbo3535 发表于 2013-5-6 17:33
呵呵,可能命题有点问题。用"关于VBA数组运算速度"这个可能更好一点。算了,我只是一个初学者。其实,发这 ...


你已经得出了一些结论:
尽量不用Index函数截取数组的一行或一列
还有就是尽量不用Transpose函数转置
处理数组用循环是正道
记得5年前向zldccmx老朽老师请教超过65536行怎么分段用Transpose处理,有位坛友就给出了,用循环比Transpose函数转置快的结论

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 18:22 | 显示全部楼层
zhaogang1960 发表于 2013-5-6 17:37
你已经得出了一些结论:
尽量不用Index函数截取数组的一行或一列
还有就是尽量不用Transpose函数转置 ...

谢谢,赵老师!
     上次,我以为1维数组对单元格来说是行(垂直列),为什么要转置?我被搞晕了!
     有个前辈告诉我:“对于单元格区域来说, 一维数组是"水平"的, 转置是为了变成"垂直"的!”
     为了一次性给直接赋值给单元格,不管是一行多列、多行一列、多行多列,我都直接声明成2维数组!别把2维的行和列搞错,就直接赋值给单元格了!不知道,这种做法在效率上可取吗?

TA的精华主题

TA的得分主题

发表于 2013-5-6 18:42 | 显示全部楼层
jinbo3535 发表于 2013-5-6 18:22
谢谢,赵老师!
     上次,我以为1维数组对单元格来说是行(垂直列),为什么要转置?我被搞晕了!
   ...

二维数组从几何意义上看对应着一个面,恰好和工作表区域对应,不管什么情况二维数组都是适应的
但一维数组写到区域中只能是一行,相当于一个只有一行的二维数组,也就是水平"的,如果要把一维数组输出到一列中就需要转置
通常可以一定一个只有一列的二维数组来代替这个一维数组,以便输出到一列中,而不使用Transpose

TA的精华主题

TA的得分主题

 楼主| 发表于 2013-5-6 18:59 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
zhaogang1960 发表于 2013-5-6 18:42
二维数组从几何意义上看对应着一个面,恰好和工作表区域对应,不管什么情况二维数组都是适应的
但一维数 ...

嗯嗯{:soso_e181:}
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-28 13:51 , Processed in 0.044275 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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