设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

返回列表 发新帖
查看: 2560|回复: 6
打印 上一主题 下一主题

[模块/函数] HackVBASpeed 之进制转换,之二进制转十进制.极限挑战

[复制链接]
跳转到指定楼层
1#
发表于 2015-8-9 11:10:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
标题有点浮夸了, 各位看官随便拍{:soso_e112:}, 有好的代码尽管来挑战{:soso_e129:}


进制转换基本在VBA常常遇到, 也是最基础的函数, 之前写的转换今天看来如果进行深度优化, 速度提升可能有100倍.


0. 不限语言(汇编,C,VB,API, TLB都可以),
1. 能在VBA环境调用,
2. 能完成1~32位内长度的二进制字符串转换


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 分享淘帖 订阅订阅
2#
 楼主| 发表于 2015-8-9 11:19:13 | 只看该作者
这个我目前收集到VBA速度最快的二进制转十进制, 德国人写的, 但可惜只能定长字符串(32字符长度)
当然这是我收集,不是我写的, 如果要重写定长转换, 速度还是很容易超过它的. 但定长的实用性不强, 写出后意义也不大.



Public Function BitToLong04(bitexpr As String) As Long
' by G.Beckmann, G.Beckmann@NikoCity.de, 20001230
' based on BitToLong03 by Egbert Nierop, egbert_nierop@goovy.hotmail.com, 20001228
    Static t%(31): Dim asc0%

    If Len(bitexpr) <> 32 Then Exit Function

    RtlMoveMemory t(0), ByVal StrPtr(bitexpr), 64
    asc0 = KeyCodeConstants.vbKey0

    BitToLong04 = t(1) - asc0
    BitToLong04 = 2 * BitToLong04 + t(2) - asc0
    BitToLong04 = 2 * BitToLong04 + t(3) - asc0
    BitToLong04 = 2 * BitToLong04 + t(4) - asc0
    BitToLong04 = 2 * BitToLong04 + t(5) - asc0
    BitToLong04 = 2 * BitToLong04 + t(6) - asc0
    BitToLong04 = 2 * BitToLong04 + t(7) - asc0
    BitToLong04 = 2 * BitToLong04 + t(8) - asc0
    BitToLong04 = 2 * BitToLong04 + t(9) - asc0
    BitToLong04 = 2 * BitToLong04 + t(10) - asc0
    BitToLong04 = 2 * BitToLong04 + t(11) - asc0
    BitToLong04 = 2 * BitToLong04 + t(12) - asc0
    BitToLong04 = 2 * BitToLong04 + t(13) - asc0
    BitToLong04 = 2 * BitToLong04 + t(14) - asc0
    BitToLong04 = 2 * BitToLong04 + t(15) - asc0
    BitToLong04 = 2 * BitToLong04 + t(16) - asc0
    BitToLong04 = 2 * BitToLong04 + t(17) - asc0
    BitToLong04 = 2 * BitToLong04 + t(18) - asc0
    BitToLong04 = 2 * BitToLong04 + t(19) - asc0
    BitToLong04 = 2 * BitToLong04 + t(20) - asc0
    BitToLong04 = 2 * BitToLong04 + t(21) - asc0
    BitToLong04 = 2 * BitToLong04 + t(22) - asc0
    BitToLong04 = 2 * BitToLong04 + t(23) - asc0
    BitToLong04 = 2 * BitToLong04 + t(24) - asc0
    BitToLong04 = 2 * BitToLong04 + t(25) - asc0
    BitToLong04 = 2 * BitToLong04 + t(26) - asc0
    BitToLong04 = 2 * BitToLong04 + t(27) - asc0
    BitToLong04 = 2 * BitToLong04 + t(28) - asc0
    BitToLong04 = 2 * BitToLong04 + t(29) - asc0
    BitToLong04 = 2 * BitToLong04 + t(30) - asc0
    BitToLong04 = t(31) - asc0 + 2 * BitToLong04
    If t(0) <> asc0 Then BitToLong04 = BitToLong04 Or &H80000000
End Function



点击这里给我发消息

3#
发表于 2015-8-10 08:59:13 | 只看该作者
赞一个!
回复

使用道具 举报

4#
 楼主| 发表于 2015-8-10 12:49:38 | 只看该作者

这不是我的代码,=会上我的代码,再给我点个赞.我的意思是挑战他的速度.
5#
发表于 2015-8-10 16:47:17 | 只看该作者
静等大神们过招
6#
 楼主| 发表于 2015-8-10 17:42:09 | 只看该作者

我是业余玩玩, 凑个热闹{:soso_e121:}


搞了半天, 由于那个德国人已经进行多版 的优化. 超过他不容易


  1. '二进制 转 十进制.
  2. '1.仅作对比使用.
  3. '2.仅32位定长的二进制字符串.
  4. Function BinToDecV6(BinString As String) As Long

  5.     If LenB(BinString) <> 64& Then Exit Function
  6.    
  7.     Static saiShare() As Integer
  8.     Static sudtShare As UDT_SafeArray1D

  9.     '//1.初始化
  10.     With sudtShare
  11.         If .cDims Then      '为了速度, 不采用 【If .cDims = 0 Then】, 因为条件判定式为 boolean = short int.
  12.         Else
  13.             '初始化数组
  14.             .cDims = 1
  15.             .cbElements = 2
  16.             .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE
  17.             .clocks = 1     '防止 VB 在卸载或中止时销毁, 因为描述符为手动栈区分配
  18.             .cElements = 32            '元素数量
  19.             PtrArr(saiShare) = VarPtr(sudtShare)    '数组变量赋值(描述符的首地址)
  20.             '初始化数据表
  21.             Static salDate1(0 To 31) As Long
  22.             Dim i As Long
  23.             For i = 0 To 31
  24.                 salDate1(i) = ShL(1, i)
  25.             Next
  26.         End If
  27.         .pvData = StrPtr(BinString)    '联接字符串数据
  28.         
  29.         '//2.转换数据
  30.         If saiShare(0) And &H1 Then BinToDecV6 = salDate1(31)
  31.         If saiShare(1) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(30)
  32.         If saiShare(2) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(29)
  33.         If saiShare(3) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(28)
  34.         If saiShare(4) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(27)
  35.         If saiShare(5) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(26)
  36.         If saiShare(6) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(25)
  37.         If saiShare(7) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(24)
  38.         If saiShare(8) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(23)
  39.         If saiShare(9) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(22)
  40.         If saiShare(10) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(21)
  41.         If saiShare(11) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(20)
  42.         If saiShare(12) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(19)
  43.         If saiShare(13) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(18)
  44.         If saiShare(14) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(17)
  45.         If saiShare(15) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(16)
  46.         If saiShare(16) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(15)
  47.         If saiShare(17) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(14)
  48.         If saiShare(18) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(13)
  49.         If saiShare(19) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(12)
  50.         If saiShare(20) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(11)
  51.         If saiShare(21) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(10)
  52.         If saiShare(22) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(9)
  53.         If saiShare(23) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(8)
  54.         If saiShare(24) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(7)
  55.         If saiShare(25) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(6)
  56.         If saiShare(26) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(5)
  57.         If saiShare(27) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(4)
  58.         If saiShare(28) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(3)
  59.         If saiShare(29) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(2)
  60.         If saiShare(30) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(1)
  61.         If saiShare(31) And &H1 Then BinToDecV6 = BinToDecV6 Or salDate1(0)
  62.         
  63.         '//3.清理工作
  64.         .pvData = 0&    '断开联接
  65.     End With
  66.    
  67. End Function
复制代码


速度对比
比德国人的快了14.23%

本帖子中包含更多资源

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

x
7#
 楼主| 发表于 2015-8-10 20:55:01 | 只看该作者
又简化了一个
速度更快, 这个应该是VB下的极限版本了. 即使用C写估计也就这样了
  1. Function BinToDecV62(BinString As String) As Long
  2.     Static saiShare() As Integer, sudtShare As UDT_SafeArray1D
  3.     '//1.初始化
  4.     If LenB(BinString) <> 64& Then Exit Function
  5.     With sudtShare
  6.         If .cDims Then      '为了速度, 不采用 【If .cDims = 0 Then】, 因为条件判定式为 boolean = short int.
  7.         Else
  8.             '初始化数组
  9.             .cDims = 1
  10.             .cbElements = 2
  11.             .fFeatures = FADF_AUTO Or FADF_FIXEDSIZE
  12.             .clocks = 1     '防止 VB 在卸载或中止时销毁, 因为描述符为手动栈区分配
  13.             .cElements = 32            '元素数量
  14.             PtrArr(saiShare) = VarPtr(sudtShare)    '数组变量赋值(描述符的首地址)
  15.         End If
  16.         .pvData = StrPtr(BinString)    '联结字符串数据

  17.         '//2.转换数据
  18.         If saiShare(0) And &H1 Then BinToDecV62 = &H80000000
  19.         If saiShare(1) And &H1 Then BinToDecV62 = BinToDecV62 Or &H40000000
  20.         If saiShare(2) And &H1 Then BinToDecV62 = BinToDecV62 Or &H20000000
  21.         If saiShare(3) And &H1 Then BinToDecV62 = BinToDecV62 Or &H10000000
  22.         If saiShare(4) And &H1 Then BinToDecV62 = BinToDecV62 Or &H8000000
  23.         If saiShare(5) And &H1 Then BinToDecV62 = BinToDecV62 Or &H4000000
  24.         If saiShare(6) And &H1 Then BinToDecV62 = BinToDecV62 Or &H2000000
  25.         If saiShare(7) And &H1 Then BinToDecV62 = BinToDecV62 Or &H1000000
  26.         If saiShare(8) And &H1 Then BinToDecV62 = BinToDecV62 Or &H800000
  27.         If saiShare(9) And &H1 Then BinToDecV62 = BinToDecV62 Or &H400000
  28.         If saiShare(10) And &H1 Then BinToDecV62 = BinToDecV62 Or &H200000
  29.         If saiShare(11) And &H1 Then BinToDecV62 = BinToDecV62 Or &H100000
  30.         If saiShare(12) And &H1 Then BinToDecV62 = BinToDecV62 Or &H80000
  31.         If saiShare(13) And &H1 Then BinToDecV62 = BinToDecV62 Or &H40000
  32.         If saiShare(14) And &H1 Then BinToDecV62 = BinToDecV62 Or &H20000
  33.         If saiShare(15) And &H1 Then BinToDecV62 = BinToDecV62 Or &H10000
  34.         If saiShare(16) And &H1 Then BinToDecV62 = BinToDecV62 Or &H8000&
  35.         If saiShare(17) And &H1 Then BinToDecV62 = BinToDecV62 Or &H4000&
  36.         If saiShare(18) And &H1 Then BinToDecV62 = BinToDecV62 Or &H2000&
  37.         If saiShare(19) And &H1 Then BinToDecV62 = BinToDecV62 Or &H1000&
  38.         If saiShare(20) And &H1 Then BinToDecV62 = BinToDecV62 Or &H800&
  39.         If saiShare(21) And &H1 Then BinToDecV62 = BinToDecV62 Or &H400&
  40.         If saiShare(22) And &H1 Then BinToDecV62 = BinToDecV62 Or &H200&
  41.         If saiShare(23) And &H1 Then BinToDecV62 = BinToDecV62 Or &H100&
  42.         If saiShare(24) And &H1 Then BinToDecV62 = BinToDecV62 Or &H80&
  43.         If saiShare(25) And &H1 Then BinToDecV62 = BinToDecV62 Or &H40&
  44.         If saiShare(26) And &H1 Then BinToDecV62 = BinToDecV62 Or &H20&
  45.         If saiShare(27) And &H1 Then BinToDecV62 = BinToDecV62 Or &H10&
  46.         If saiShare(28) And &H1 Then BinToDecV62 = BinToDecV62 Or &H8&
  47.         If saiShare(29) And &H1 Then BinToDecV62 = BinToDecV62 Or &H4&
  48.         If saiShare(30) And &H1 Then BinToDecV62 = BinToDecV62 Or &H2&
  49.         If saiShare(31) And &H1 Then BinToDecV62 = BinToDecV62 Or &H1&

  50.         '//3.清理工作
  51.         .pvData = 0&    '断开联结
  52.     End With

  53. End Function
复制代码


测试结果如下, 与2楼的BitToLong04 相比, 速度竟然提升了33.87%.


PS:把自己以前写的二进制转换十进制代码 作了一下对比. 速度是之前的25倍之多

本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-5-7 00:07 , Processed in 0.106945 second(s), 31 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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