开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 431|回复: 15
收起左侧

[已解决] 循环十万 百万 高效率的写法 求一个

 关闭 [复制链接]
结帖率:93% (224/241)
发表于 2024-10-12 22:38:50 | 显示全部楼层 |阅读模式   上海市上海市
33精币
  
子程序名返回值类型公开备 注
子程序1  
变量名类 型静态数组备 注
时间戳文本型 
a整数型 
测试文本型 
计次循环首 (100000, a)
测试 = 到大写 (取文本左边 (取数据摘要 (到字节集 (时间戳 + 到文本 (a)到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + “+”到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)) + 到文本 (取随机数 (1, 9)))), 到整数 (16)))
计次循环尾 ()


i支持库列表   支持库注释   
dp1数据操作支持库一
spec特殊功能支持库

最佳答案

查看完整内容

我来交作业了,速度应该很快了这个过程,10万次本机测试58毫秒 代码阅读性差,注重解题过程哈 源码预览: [e=1].版本 2 .支持库 spec .程序集 程序集1 .子程序 _启动子程序, 整数型 .局部变量 启动时间, 长整数型 .局部变量 结束时间, 长整数型 QueryPerformanceCounter (启动时间) _临时子程序 () QueryPerformanceCounter (结束时间) 调试输出 (结束时间 - 启动时间, (结束时间 - 启动时间) ÷ 10000) 返回 (0) .子程序 ...

点评

帮你写了一份10万次58毫秒的,代码在审核,等等就看到了   福建省宁德市  发表于 2024-10-13 00:24

回答提醒:如果本帖被关闭无法回复,您有更好的答案帮助楼主解决,请发表至 源码区 可获得加分喔。
友情提醒:本版被采纳的主题可在 申请荣誉值 页面申请荣誉值,获得 1点 荣誉值,荣誉值可兑换荣誉会员、终身vip用户组。
快捷通道:申请荣誉值无答案申请取消悬赏投诉有答案未采纳为最佳

本帖被以下淘专辑推荐:

结帖率:95% (19/20)

签到天数: 22 天

发表于 2024-10-12 22:38:51 | 显示全部楼层   福建省宁德市
我来交作业了,速度应该很快了这个过程,10万次本机测试58毫秒
代码阅读性差,注重解题过程哈

源码预览:
  
窗口程序集名保 留  保 留备 注
程序集1   
子程序名返回值类型公开备 注
_启动子程序整数型 
变量名类 型静态数组备 注
启动时间长整数型 
结束时间长整数型 
QueryPerformanceCounter (启动时间)
_临时子程序 ()
QueryPerformanceCounter (结束时间)
调试输出 (结束时间 - 启动时间, (结束时间 - 启动时间) ÷ 10000)
返回 (0)
子程序名返回值类型公开备 注
_临时子程序  
变量名类 型静态数组备 注
时间戳文本型 
i整数型 
测试文本型 
测试地址整数型 
指针地址整数型 
算法缓冲区文本型 
算法缓冲区地址整数型 
' 时间戳:10
' 计次 I:6
' 随机数:11
' 符号 +:1
' -------------
' 总计:28 字节
' MD5   :32
' 大写  :16
' -------------
' 总计  :32
时间戳 = “1728746500”
' 已知最大文本的长度就32字节就够了,如果循环次数达到百万或时间戳文本长度更长,缓冲区可适当加大到40-48
测试 = 取空白文本 (32)
测试地址 = 取变量数据地址 (测试)
算法缓冲区 = 取空白文本 (104)
算法缓冲区地址 = 取变量数据地址 (算法缓冲区)
计次循环首 (100000, i)  ' 10万次58毫秒,百万次580毫秒
指针地址 = 测试地址
' 写入时间戳
写到内存 (时间戳, 指针地址, )
指针地址 = 测试地址 + 10  ' 时间戳文本长度
' 到文本(i)
_itoa (i, 指针地址, 10)
指针地址 = 指针地址 + GetStrLen (指针地址)
' 取随机数,头7次
计次循环首 (7, )
_itoa (Random (1, 9), 指针地址, 10)
指针地址 = 指针地址 + 1
计次循环尾 ()
' 中间补一个 '+'
写到内存 (“+”, 指针地址, )
指针地址 = 指针地址 + 1
' 取随机数,尾4次
计次循环首 (4, )
_itoa (Random (1, 9), 指针地址, 10)
指针地址 = 指针地址 + 1
计次循环尾 ()
' 取数据摘要
GetMd5 (测试地址, 指针地址 - 测试地址, 算法缓冲区地址, 测试地址, 7)
' 取文本左边(测试,16),直接在第16个字节的位置写入终止符\0 截断
写到内存 ({ 0 }, 测试地址 + 16, )
计次循环尾 ()
' 调试输出 (测试)
' 解释:
' 你原始的代码存在大量的整数到文本转换,每转换一次就要申请内存块(整数4294967295+\0)
' 即使在循环过程编译器等会优化这个过程,大量循环下消耗的时间还是很多的
' 其次 还存在文本相加的过程,比如:到文本(随机数)+到文本(随机数)
' 这个过程会逐字遍历文本,找到文本的终止符,实现取文本长度,然后再申请一块大内存,将文本块复制过去
' 然后再申请一块字节集的缓冲区
' 然后计算MD5时还会申请额外的内存来计算,到大小写这个过程也会重新申请内存
' 总之原始代码存在大量的申请释放内存过程
' 上面那么多代码的作用就是避免这个过程,循环过程就飞快了
子程序名返回值类型公开备 注
GetStrLen整数型 取文本型数据的长度,不包含结束0。
参数名类 型参考可空数组备 注
pAddr通用型可以是文本型或文本指针
' __asm{
' ; mov eax,dword [ebp+8]       ;字符串栈地址
' ; mov eax,dword [eax]         ;字符串堆地址
' ; test eax,eax                ;判断堆地址是否为零,比如传入空变量
' ; jz 返回
' ; lea edx,[eax+3]             ;拷贝一份字符串堆地址,+3仅为了最后运算的偏移
' ; 读入四字节:
' ; mov ebx,[eax]               ;读入4个字节
' ; add eax,4                   ;字符串指针+4
' ; lea ecx,[ebx-01010101h]     ;ebx的4字节每个字节-1
' ; not ebx                     ;ebx的4个字节逻辑取反,如-1变成1
' ; and ecx,ebx                 ;ecx=取反后的每个字节和没取反后-1的每个字节进行逻辑与
' ; and ecx,80808080h           ;判断每个字节的二进制第8位是否为1,为1则说明原字节=0
' ; jz 读入四字节               ;如果为零,表示4个字节都不为null,跳回继续循环
' ; test ecx,00008080h          ;判断null是否在前2个字节中
' ; jnz 计算长度                ;在前2个字节处理
' ; shr ecx,16                  ;不在前2字节,将ecx高16复制到低16(后2字节复制到前2字节)
' ; add eax,2                   ;字符串指针+2
' ; 计算长度:
' ; shl cl,1                    ;第1个字节逻辑左移1位,如果第1个字节为Null,则CF=1,否则即说
' ; sbb eax,edx                 ;eax=eax-edx-CF
' ; 返回:
' ; leave
' ; retn __参数大小__
' }
置入代码 ({ 139, 69, 8, 139, 0, 133, 192, 116, 44, 141, 80, 3, 139, 24, 131, 192, 4, 141, 139, 255, 254, 254, 254, 247, 211, 33, 217, 129, 225, 128, 128, 128, 128, 116, 233, 247, 193, 128, 128, 0, 0, 117, 6, 193, 233, 16, 131, 192, 2, 208, 225, 25, 208, 201, 194, 4, 0 })
返回 (0)
子程序名返回值类型公开备 注
Random整数型 取随机数,效率2.7亿/s
参数名类 型参考可空数组备 注
min整数型
max整数型
reset逻辑型
变量名类 型静态数组备 注
n整数型 
i整数型 
如果真 (reset = n = 0)
置入代码 ({ 15, 49, 133, 192, 116, 250, 137, 69, 252 })
n = i
置入代码 ({ 232, 0, 0, 0, 0, 89, 139, 85, 12, 139, 69, 8, 83, 87, 86, 139, 113, 247, 57, 208, 137, 193, 15, 79, 202, 15, 79, 208, 139, 6, 137, 199, 193, 231, 13, 49, 199, 137, 251, 193, 235, 17, 49, 251, 137, 216, 193, 224, 5, 49, 216, 41, 202, 66, 191, 255, 255, 255, 255, 15, 69, 250, 137, 6, 49, 210, 247, 247, 1, 209, 137, 200, 94, 95, 91, 201, 194, 16, 0 })
返回 (0)
子程序名返回值类型公开备 注
GetMd5  
参数名类 型参考可空数组备 注
数据地址整数型
数据长度整数型如果为文本、字节集变量,则数据长度可以填0。如果是数据指针中的部分数据,请填写数据长度。
算法缓冲区指针整数型该缓冲区大小至少为104
MD5缓冲区整数型该缓冲区大小至少为32
大小写整数型7=大写,39=小写
变量名类 型静态数组备 注
变量类型整数型 
i整数型 
MD5_Init (算法缓冲区指针)  ' 初始化
MD5_Update (算法缓冲区指针, 数据地址, 数据长度)  ' 加入需要计算的数据
MD5_Final (算法缓冲区指针)  ' 取出计算结果
' 将末尾的16字节转换到16进制
BytesToHex (算法缓冲区指针 + 88, 16, MD5缓冲区, 大小写, 0)
子程序名返回值类型公开备 注
BytesToHex整数型 
参数名类 型参考可空数组备 注
数据地址整数型字节集数据地址,取变量数据地址(字节集)
数据长度整数型字节集的长度
输出缓冲区整数型该缓冲区大小至少为:字节集长度*2;如果带分隔符,该缓冲区大小至少为:字节集长度*3
输出大小写整数型只能为两者值之一:7=大写;39=小写;
输出分隔符整数型0=无分隔符,空格=32(ascii码)
' __asm{
' ; mov esi, dword ptr [ebp +  8]           ;字节集数据地址
' ; mov ecx, dword ptr [ebp + 12]           ;字节集长度
' ; mov edi, dword ptr [ebp + 16]           ;输出缓冲区数据地址
' ; mov dh,  byte  ptr [ebp + 20]           ;7=大写;39=小写
' ; mov al,  byte  ptr [ebp + 24]           ;输出缓冲区分隔符,0=无分隔符;32=空格
' ; next_byte:                              ;循环首标签开始
' ;    test ecx, ecx                        ;自身位与比较等价于:位与(ecx,ecx)
' ;    jz done                              ;如果ecx=0,转到done标签结束,否则↓执行
' ;    mov dl,byte ptr [esi]                ;读取esi处一个字节,假设字节=254,Hex=FE
' ;    shr dl,4                             ;15=右移(254,4)
' ;    and dl,15                            ;15=位与(15,15)
' ;    add dl,'0'                           ;15+48=63
' ;    cmp dl,'9'                           ;比较 63 , 57
' ;    jbe write_byte_1                     ;如果 63 ≯ 57 则跳转
' ;    add dl,dh                            ;否则 63+7=70=F,63+39=102=f
' ; write_byte_1:                           ;写第一个字节;0-F,上面dl已经处理好了
' ;    mov byte ptr [edi],dl                ;将F写入edi中
' ;    inc edi                              ;edi 递增+1
' ;    mov dl,byte ptr [esi]                ;原先的dl已被覆盖,再次取出当前字节(254)
' ;    and dl,15                            ;14=位与(254,15)
' ;    add dl,'0'                           ;14+48=62
' ;    cmp dl,'9'                           ;比较 62 , 57
' ;    jbe write_byte_2                     ;如果 62 ≯ 57 则跳转
' ;    add dl,dh                            ;否则 62+7=69=E,62+39=101=e
' ; write_byte_2:                           ;写第二个字节
' ;    mov byte ptr [edi],dl                ;将E写入edi中
' ;    inc edi                              ;edi 递增+1
' ;    test al,al                           ;位与(al,al)
' ;    jz no_fill                           ;如果al=0,不填充分隔符,跳转标签
' ;    mov byte ptr [edi],al                ;否则将分隔符填充进edi中
' ;    inc edi                              ;edi 递增+1
' ; no_fill:
' ;    inc esi                              ;字节集数据指针递增+1
' ;    dec ecx                              ;ecx 循环递减-1
' ;    jmp next_byte                        ;跳转到循环首↑处理下一个字节
' ; done:
' ;    mov eax,dword ptr [ebp+16]           ;读取初始的输出缓冲区数据地址
' ;    cmp eax,edi                          ;初始指针和结束指针比较
' ;    jz end_ret                           ;如果两者相等,说明没处理过任何数据
' ;    mov byte ptr [edi],0                 ;否则edi末尾的分隔符设置为终止符0
' ;    mov eax,edi                          ;将edi结束指针赋值到eax
' ; end_ret:
' ;    leave                                ;清理恢复栈
' ;    retn __参数大小__                    ;32位程序的返回值储存在eax中,64位在rax
' }
置入代码 ({ 139, 117, 8, 139, 77, 12, 139, 125, 16, 138, 117, 20, 138, 69, 24, 133, 201, 116, 50, 138, 22, 192, 234, 4, 128, 226, 15, 128, 194, 48, 128, 250, 57, 118, 2, 0, 242, 136, 23, 71, 138, 22, 128, 226, 15, 128, 194, 48, 128, 250, 57, 118, 2, 0, 242, 136, 23, 71, 132, 192, 116, 3, 136, 7, 71, 70, 73, 235, 202, 139, 69, 16, 57, 248, 116, 5, 198, 7, 0, 137, 248, 201, 194, 20, 0 })
返回 (0)


i支持库列表   支持库注释   
spec特殊功能支持库


完整源码下载: demo.e (16.07 KB, 下载次数: 3)

评分

参与人数 1荣誉 +1 收起 理由
笨潴 + 1 热心帮助他人,荣誉+1,希望继续努力(*^__^*) 嘻嘻!

查看全部评分

回复

使用道具 举报

签到天数: 15 天

发表于 2024-10-12 22:44:05 | 显示全部楼层   四川省宜宾市
  
子程序名返回值类型公开备 注
_按钮1_被单击  
子程序1 ()
子程序名返回值类型公开备 注
子程序1  
变量名类 型静态数组备 注
时间戳文本型 
a整数型 
测试文本型 
计次循环首 (100000, a)
测试 = 到大写 (取文本左边 (取数据摘要 (到字节集 (时间戳 + 到文本 (a)到文本 (取随机数 (111111, 999999)) + “+”到文本 (取随机数 (11111, 99999)))), 16))
计次循环尾 ()
调试输出 (测试)


i支持库列表   支持库注释   
dp1数据操作支持库一
spec特殊功能支持库

点评

所以,再想点别的方案吧   福建省泉州市  发表于 2024-10-12 22:53
按楼主代码,随机数字文本每一位都是1-9的数,按你的代码,可能存在某一位或多个位置是0的情况   福建省泉州市  发表于 2024-10-12 22:52
回复

使用道具 举报

结帖率:100% (2/2)

签到天数: 24 天

发表于 2024-10-12 22:50:10 | 显示全部楼层   河北省邯郸市
十万百万开线程,每个线程执行不同的循环
回复

使用道具 举报

结帖率:100% (21/21)

签到天数: 24 天

发表于 2024-10-12 23:04:36 | 显示全部楼层   广东省惠州市
不要用+这样的文本追加文本内容,要用一次申请足够内存空间,然后复制内存方式把数据追加.这样就快了!思路:
https://bbs.125.la/forum.php?mod ... 14759821&extra=
回复

使用道具 举报

签到天数: 15 天

发表于 2024-10-12 23:04:53 | 显示全部楼层   四川省宜宾市
  
子程序名返回值类型公开备 注
_按钮1_被单击  
子程序1 ()
子程序名返回值类型公开备 注
子程序1  
变量名类 型静态数组备 注
时间戳文本型 
a整数型 
测试文本型 
b整数型 
c整数型 
n整数型 
计次循环首 (100000, a)
计次循环首 (11, n)
b = 取随机数 (1, 9)
计次循环首 (n - 1, )
b = b × 10
计次循环尾 ()
c = c + b
计次循环尾 ()
计次循环首 (11, )
a = a × 10
计次循环尾 ()
c = a + c
测试 = 到大写 (取文本左边 (取数据摘要 (到字节集 (时间戳 + 到文本 (c))), 16))
计次循环尾 ()
调试输出 (测试)


i支持库列表   支持库注释   
dp1数据操作支持库一
spec特殊功能支持库

点评

不过我对他这代码怎么改,毫无头绪,哈哈哈   福建省泉州市  发表于 2024-10-12 23:11
循环里b=bx10,建议改用 求次方(),他本来在求效率写法,现在这循环的写法感觉和他原本的写法不相上下了   福建省泉州市  发表于 2024-10-12 23:11
回复

使用道具 举报

签到天数: 15 天

发表于 2024-10-12 23:18:57 | 显示全部楼层   四川省宜宾市
你用点评真是没法沟通,他那个方法有到文本() 效率慢得我都等不到出结果,改次方确实快点

  
子程序名返回值类型公开备 注
_按钮1_被单击  
子程序1 ()
子程序名返回值类型公开备 注
子程序1  
变量名类 型静态数组备 注
时间戳文本型 
a整数型 
测试文本型 
b整数型 
c整数型 
n整数型 
计次循环首 (100000, a)
计次循环首 (11, n)
b = 取随机数 (1, 9)
b = b × 求次方 (10, n - 1)
c = c + b
计次循环尾 ()
a = a × 求次方 (10, 11)
c = a + c
测试 = 到大写 (取文本左边 (取数据摘要 (到字节集 (时间戳 + 到文本 (c))), 16))
计次循环尾 ()
调试输出 (测试)


i支持库列表   支持库注释   
dp1数据操作支持库一
spec特殊功能支持库

回复

使用道具 举报

结帖率:98% (45/46)

签到天数: 10 天

发表于 2024-10-12 23:54:36 | 显示全部楼层   新疆维吾尔自治区阿克苏地区
这是用来测机器性能的吗?
回复

使用道具 举报

结帖率:95% (19/20)

签到天数: 22 天

发表于 2024-10-13 00:39:30 | 显示全部楼层   福建省宁德市
  
源码预览:
窗口程序集名保 留  保 留备 注
程序集1   
子程序名返回值类型公开备 注
_启动子程序整数型 
变量名类 型静态数组备 注
启动时间长整数型 
结束时间长整数型 
QueryPerformanceCounter (启动时间)
_临时子程序 ()
QueryPerformanceCounter (结束时间)
调试输出 (结束时间 - 启动时间, (结束时间 - 启动时间) ÷ 10000)
返回 (0)
子程序名返回值类型公开备 注
_临时子程序  
变量名类 型静态数组备 注
时间戳文本型 
i整数型 
测试文本型 
测试地址整数型 
指针地址整数型 
算法缓冲区文本型 
算法缓冲区地址整数型 
' 时间戳:10
' 计次 I:6
' 随机数:11
' 符号 +:1
' -------------
' 总计:28 字节
' MD5   :32
' 大写  :16
' -------------
' 总计  :32
时间戳 = “1728746500”
' 已知最大文本的长度就32字节就够了,如果循环次数达到百万或时间戳文本长度更长,缓冲区可适当加大到40-48
测试 = 取空白文本 (32)
测试地址 = 取变量数据地址 (测试)
算法缓冲区 = 取空白文本 (104)
算法缓冲区地址 = 取变量数据地址 (算法缓冲区)
计次循环首 (100000, i)  ' 10万次58毫秒,百万次580毫秒
指针地址 = 测试地址
' 写入时间戳
写到内存 (时间戳, 指针地址, )
指针地址 = 测试地址 + 10  ' 时间戳文本长度
' 到文本(i)
_itoa (i, 指针地址, 10)
指针地址 = 指针地址 + GetStrLen (指针地址)
' 取随机数,头7次
计次循环首 (7, )
_itoa (Random (1, 9), 指针地址, 10)
指针地址 = 指针地址 + 1
计次循环尾 ()
' 中间补一个 '+'
写到内存 (“+”, 指针地址, )
指针地址 = 指针地址 + 1
' 取随机数,尾4次
计次循环首 (4, )
_itoa (Random (1, 9), 指针地址, 10)
指针地址 = 指针地址 + 1
计次循环尾 ()
' 取数据摘要
GetMd5 (测试地址, 指针地址 - 测试地址, 算法缓冲区地址, 测试地址, 7)
' 取文本左边(测试,16),直接在第16个字节的位置写入终止符\0 截断
写到内存 ({ 0 }, 测试地址 + 16, )
计次循环尾 ()
' 调试输出 (测试)
' 解释:
' 你原始的代码存在大量的整数到文本转换,每转换一次就要申请内存块(整数4294967295+\0)
' 即使在循环过程编译器等会优化这个过程,大量循环下消耗的时间还是很多的
' 其次 还存在文本相加的过程,比如:到文本(随机数)+到文本(随机数)
' 这个过程会逐字遍历文本,找到文本的终止符,实现取文本长度,然后再申请一块大内存,将文本块复制过去
' 然后再申请一块字节集的缓冲区
' 然后计算MD5时还会申请额外的内存来计算,到大小写这个过程也会重新申请内存
' 总之原始代码存在大量的申请释放内存过程
' 上面那么多代码的作用就是避免这个过程,循环过程就飞快了



i支持库列表   支持库注释   
spec特殊功能支持库

完整源码下载: demo.e (16.07 KB, 下载次数: 5)

点评

高,实在是高,用指针,我都不知道这根针在哪里   浙江省嘉兴市  发表于 2024-10-13 10:48
回复

使用道具 举报

结帖率:93% (224/241)

签到天数: 19 天

 楼主| 发表于 2024-10-13 09:45:07 | 显示全部楼层   上海市上海市
大漠小鸟 发表于 2024-10-13 00:39
[e=1]源码预览:
.版本 2
.支持库 spec

我的慢慢阅读下  ,,大佬费心
回复

使用道具 举报

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

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

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