改进2006-9-9的练手程序,原始地址http://blog.csdn.net/pig4210/archive/2006/09/10/1202947.aspx
感谢jailu的算法,程序的速度上有数量级的提高,已经跑进1分钟了。
; 结果我看他的源程序,就是不明白,以为他使用的是字串操作,先是以为这也是一个不错的方法。但ASM实现起来很困难
; 但我就不信了,我用API,结果一跑,速度竟然慢了一倍。就郁闷了
; 后来,jailu给我解释了,才恍然大悟,是,原来是我把他的程序理解错了,相当丢人
; 再看一下程序,对比一下解释,jailu果然观察入微,找到了更细的数字关系,算法不同,果然能跑进3分钟
; 他的解释是:我把多数的运算都变成加法了。是啊,加法是CPU的基本运算啊,当然最快
; 有了好算法不用那不是我的风格不是?,马上写
; 先是完全套用jailu的算法,跑到2分钟,跟他的程序时间一样,竟然没快多少
; 后来我在==0的分支回用了除10取余,竟然跑进了2分钟,是79秒。
; 但是在改动的过程中,发现,竟然用局部变量反而比直接使用寄存器快,不明所以
; 拿程序给jailu跑了一下,他的机子性能好,竟然跑进了50秒,最快跑到48578 ms,相当可观
; 而jailu把自己的程序也回改了除10取余,性能却没有得到很大的提高。也不明白怎么回事。
; 刚刚半路关掉Q,我的机子里这个程序也竟然跑进了1分钟。
; 而方才加了一个跳步,速度又快了,嘿嘿。在我机子里能保证跑进1分钟了,jailu那里跑到32秒。嘿嘿。
; 估计这个程序也被写到当前的极限了,但或者有更强的算法没有被发现,
.586
.model flat , stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
include masm32.inc
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
includelib masm32.lib
include C:masm32macrosMACROS.ASM
max equ 1111111110
max1 equ 2600001
max2 equ 1111111110
.const
xten dd 1 , 10 , 100 , 1000 , 10000 , 100000 , 1000000 , 10000000 , 100000000 , 1000000000
.data
fmt_num db " %d " , 0
fmt_my db " %d 耗时 %d ms. " , 10 , 0
fmt_time db " 任务结束,共耗时 %d ms . " , 0
.data?
hInstance dd ?
hWinMain dd ?
tmpstr db 128 dup (?)
x dd ?
time dd ?
.code
_main proc
LOCAL @cout
pushad
invoke GetTickCount
mov time , eax
xor esi , esi
mov @cout , esi
mov edi , 10
xor ebx , ebx
.while ebx < = 1111111110
mov eax , ebx
xor edx , edx
div edi
.if edx == 1
inc esi
.elseif edx == 0
mov @cout , edx
.while eax > 0
xor edx , edx
div edi
.if edx == 1
inc @cout
.endif
.endw
.elseif edx == 2
add esi , @cout
mov ecx , ebx
add ebx , 8
.if (esi > = ecx) && (esi < = ebx)
sub ebx , 8
sub esi , @cout
.else
add esi , @cout
add esi , @cout
add esi , @cout
add esi , @cout
add esi , @cout
add esi , @cout
add esi , @cout
.continue
.endif
.endif
add esi , @cout
.if esi == ebx
invoke GetTickCount
sub eax , time
invoke wsprintf , addr tmpstr , addr fmt_my , ebx , eax
invoke StdOut , addr tmpstr
.endif
inc ebx
.endw
invoke GetTickCount
sub eax , time
invoke wsprintf , addr tmpstr , addr fmt_time , eax
invoke StdOut , addr tmpstr
popad
ret
_main endp
start:
invoke GetModuleHandle , NULL
mov hInstance , eax
invoke _main
invoke ExitProcess , NULL
end start
以下分别为两个版本的输出:
0 耗时 0 ms.
1 耗时 10 ms.
199981 耗时 20 ms.
199982 耗时 20 ms.
199983 耗时 20 ms.
199984 耗时 20 ms.
199985 耗时 20 ms.
199986 耗时 20 ms.
199987 耗时 30 ms.
199988 耗时 30 ms.
199989 耗时 30 ms.
199990 耗时 30 ms.
200000 耗时 30 ms.
200001 耗时 40 ms.
1599981 耗时 120 ms.
1599982 耗时 120 ms.
1599983 耗时 120 ms.
1599984 耗时 120 ms.
1599985 耗时 120 ms.
1599986 耗时 120 ms.
1599987 耗时 120 ms.
1599988 耗时 120 ms.
1599989 耗时 120 ms.
1599990 耗时 120 ms.
2600000 耗时 190 ms.
2600001 耗时 190 ms.
13199998 耗时 761 ms.
35000000 耗时 2013 ms.
35000001 耗时 2013 ms.
35199981 耗时 2043 ms.
35199982 耗时 2043 ms.
35199983 耗时 2043 ms.
35199984 耗时 2043 ms.
35199985 耗时 2043 ms.
35199986 耗时 2043 ms.
35199987 耗时 2043 ms.
35199988 耗时 2043 ms.
35199989 耗时 2043 ms.
35199990 耗时 2053 ms.
35200000 耗时 2053 ms.
35200001 耗时 2053 ms.
117463825 耗时 6920 ms.
500000000 耗时 31395 ms.
500000001 耗时 31395 ms.
500199981 耗时 31415 ms.
500199982 耗时 31415 ms.
500199983 耗时 31415 ms.
500199984 耗时 31415 ms.
500199985 耗时 31415 ms.
500199986 耗时 31425 ms.
500199987 耗时 31425 ms.
500199988 耗时 31425 ms.
500199989 耗时 31425 ms.
500199990 耗时 31425 ms.
500200000 耗时 31425 ms.
500200001 耗时 31425 ms.
501599981 耗时 31545 ms.
501599982 耗时 31545 ms.
501599983 耗时 31545 ms.
501599984 耗时 31545 ms.
501599985 耗时 31545 ms.
501599986 耗时 31545 ms.
501599987 耗时 31545 ms.
501599988 耗时 31545 ms.
501599989 耗时 31545 ms.
501599990 耗时 31545 ms.
502600000 耗时 31605 ms.
502600001 耗时 31605 ms.
513199998 耗时 32296 ms.
535000000 耗时 33688 ms.
535000001 耗时 33688 ms.
535199981 耗时 33699 ms.
535199982 耗时 33709 ms.
535199983 耗时 33709 ms.
535199984 耗时 33709 ms.
535199985 耗时 33709 ms.
535199986 耗时 33709 ms.
535199987 耗时 33709 ms.
535199988 耗时 33709 ms.
535199989 耗时 33709 ms.
535199990 耗时 33719 ms.
535200000 耗时 33719 ms.
535200001 耗时 33719 ms.
1111111110 耗时 69190 ms.
任务结束,共耗时 69190 ms .
加了跳步较果的程序:
0 耗时 0 ms.
1 耗时 0 ms.
199981 耗时 10 ms.
199982 耗时 10 ms.
199983 耗时 10 ms.
199984 耗时 10 ms.
199985 耗时 10 ms.
199986 耗时 10 ms.
199987 耗时 10 ms.
199988 耗时 10 ms.
199989 耗时 10 ms.
199990 耗时 10 ms.
200000 耗时 10 ms.
200001 耗时 10 ms.
1599981 耗时 50 ms.
1599982 耗时 60 ms.
1599983 耗时 60 ms.
1599984 耗时 60 ms.
1599985 耗时 60 ms.
1599986 耗时 60 ms.
1599987 耗时 60 ms.
1599988 耗时 60 ms.
1599989 耗时 60 ms.
1599990 耗时 60 ms.
2600000 耗时 90 ms.
2600001 耗时 100 ms.
35000000 耗时 1032 ms.
35000001 耗时 1032 ms.
35199981 耗时 1052 ms.
35199982 耗时 1062 ms.
35199983 耗时 1062 ms.
35199984 耗时 1062 ms.
35199985 耗时 1072 ms.
35199986 耗时 1072 ms.
35199987 耗时 1082 ms.
35199988 耗时 1082 ms.
35199989 耗时 1082 ms.
35199990 耗时 1092 ms.
35200000 耗时 1092 ms.
35200001 耗时 1102 ms.
500000000 耗时 16824 ms.
500000001 耗时 16824 ms.
500199981 耗时 16824 ms.
500199982 耗时 16834 ms.
500199983 耗时 16834 ms.
500199984 耗时 16834 ms.
500199985 耗时 16834 ms.
500199986 耗时 16834 ms.
500199987 耗时 16844 ms.
500199988 耗时 16844 ms.
500199989 耗时 16844 ms.
500199990 耗时 16844 ms.
500200000 耗时 16844 ms.
500200001 耗时 16844 ms.
501599981 耗时 16894 ms.
501599982 耗时 16894 ms.
501599983 耗时 16894 ms.
501599984 耗时 16894 ms.
501599985 耗时 16904 ms.
501599986 耗时 16904 ms.
501599987 耗时 16904 ms.
501599988 耗时 16904 ms.
501599989 耗时 16904 ms.
501599990 耗时 16904 ms.
502600000 耗时 16945 ms.
502600001 耗时 16955 ms.
535000000 耗时 18046 ms.
535000001 耗时 18046 ms.
535199981 耗时 18056 ms.
535199982 耗时 18056 ms.
535199983 耗时 18056 ms.
535199984 耗时 18056 ms.
535199985 耗时 18066 ms.
535199986 耗时 18066 ms.
535199987 耗时 18066 ms.
535199988 耗时 18066 ms.
535199989 耗时 18066 ms.
535199990 耗时 18066 ms.
535200000 耗时 18066 ms.
535200001 耗时 18066 ms.
1111111110 耗时 37474 ms.
任务结束,共耗时 37474 ms .