设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

123下一页
返回列表 发新帖
查看: 6453|回复: 23

[API] 拷贝字符串速度之对比: CopyMemory 与 动态字节数组

[复制链接]
发表于 2015-6-9 16:33:33 | 显示全部楼层 |阅读模式
好久没写代码了, 前几天有看到说VBA调用API很慢(CopyMemory), 我听了很费解, 也不好说明, 只好用数据说话.
所以做了个有趣的的测试.主要代码如下:
Public ShareInt16(7) As Integer     '整形, 128位, 2*08=16个字节
Private Function TestSink_TestFun2() As Long
    Dim varRet As Long, i As Long, strTmp As String, bytData() As Byte
    If mblnSkipRun = False Then
        '测试函数与代码放入此
        strTmp = "&H7FFFABCD"
        bytData = strTmp
    End If
End Function


Private Function TestSink_TestFun1() As Long
    Dim varRet As Long, i As Long, strTmp As String
    If mblnSkipRun = False Then
        '测试函数与代码放入此
        strTmp = "7FFFABCD"
        CopyMemory ShareInt16(0), ByVal StrPtr(strTmp), 16&
    End If
End Function



图片如下:




结论:
CopyMemory比 VBA的动态字节数组, 整整快了2倍多
调用CopyMemory真的很快(后台调用指令很少)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

评分

参与人数 1经验 +10 收起 理由
tmtony + 10 好代码

查看全部评分

点击这里给我发消息

发表于 2015-6-9 16:35:51 | 显示全部楼层
赞一个!!
回复

使用道具 举报

发表于 2015-6-9 16:44:24 | 显示全部楼层
少了"&h"当然更快{:soso_e120:}
 楼主| 发表于 2015-6-9 17:14:56 | 显示全部楼层

呵呵,多了一个32位, CPU多跑了一次.
16字节对比20字节差25%, 算一下一次还是 CopyMemory 快1.5倍

其实重点不在此, 我只是说明调用API得当, 速度照样杠杠的

点击这里给我发消息

发表于 2015-6-9 17:47:15 | 显示全部楼层
是的,用系统内置的 有时速度会快不少,不过,对有些用户,可能 对API有恐惧

另对你那个测试结果报告是如何做出来,我反而更感兴趣:)

点击这里给我发消息

发表于 2015-6-10 05:08:46 来自手机 | 显示全部楼层
这好象没可比性,一个string,一个lnt,Api用指针引用会在排序比较快些,但复制会差不多,还要分配内存

点击这里给我发消息

发表于 2015-6-10 12:34:10 | 显示全部楼层
也贴一篇 有关CopyMemory的相关文章
[API] 【高级编程】VBA及VB中利用CopyMemory使用指针
http://www.office-cn.net/thread-120040-1-1.html
 楼主| 发表于 2015-6-11 18:26:06 | 显示全部楼层
再深入一点, 两个问题?
1, 为什么 abytData = strTmp 字节数组赋值要慢? 它慢在哪?
2, 为什么 CopyMemory 要快呢? 它快在哪?
再深入要把这个问题弄懂, 就要对COM有所了解. 我也是忘记得差不多了.

1.1 它慢在, VB要多创建一个数组:SafeArray(动态数组的创建, 这个过程比较麻烦, 申请内存,指令要多) 然后再是数据复制.

2.1, 虽然CopyMemory是API,在"kernel32.dll"库中, 但这个库, 从系统启动时, 已经加载在内存中, 你VB中引用时, 已经VB无需再次加载, windows不过内存中调用罢了.
2.2 当然 ShareInt16 是公共申明的静态数组, 也有这点原因


 楼主| 发表于 2015-6-11 18:30:56 | 显示全部楼层
今天又进行一个比较
MID语句 对 CopyMemory 哪个快
    If mblnSkipRun = False Then
        Mid(msTmp1, 1&, 4&) = msTmp2   
    End If

CopyMemory 要多一句
    If mblnSkipRun = False Then
        mlTmp = StrPtr(msTmp2)
        CopyMemory ByVal StrPtr(mlTmp), ByVal msTmp2, 8&
    End If
注意: 是 MID语句 不是 MID函数

为了更公平, 这次全是公共申明
 楼主| 发表于 2015-6-11 19:36:58 | 显示全部楼层
本帖最后由 wang1999 于 2015-6-11 19:54 编辑

代码改了一下:
Mid(msTmp1, 1&, 4&) = msTmp2

CopyMemory ByVal StrPtr(msTmp1), ByVal StrPtr(msTmp2), 8&

'初始化数据
Private Sub cmdInitialize_Click()
    msTmp1 = String(16, vbNullChar)
    msTmp2 = "abcdef12345"
End Sub


结果如下:



思考:
两者竟然一不分仲伯. 虽然两次取指针并复制 StrPtr
1.说明  StrPtr 只是一条简单LONG赋值, 速度是相当快
2.少两条指令复制, MID 应该要快呀?  原来 Variant (String) 这个是输入值, MID慢在这里了.
3. copymemory 则慢在 两条  StrPtr 复制, 所以综合2,3点 两者速度基本一致
所以:
在MID语句不方便使用的情况下, copymemory 与指针结合 可以作为VBA的一个操作语句, 在代码中随意使用, 有更多的灵活性, 且不仅不会牺牲性能.



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

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

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-3-29 14:32 , Processed in 0.110509 second(s), 38 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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