基礎運算對時間複雜度影響的分析




本文章主要研究各種變量類型加減乘除以及取模所耗費時間的差異

以下不作特殊說明均爲1e91e9次操作,時間均以毫秒記,測量多次取平均數

由於機子問題,測得時間可能不同,但其快慢比較相對可信(3232XPXP系統 版本20022002 )



forfor循環


for(int i=1;i<=1000000000;++i);

++ii2145ms2145ms

ii++ : 2153ms2153ms

ii+=112130ms2130ms

12e91-2e9ii+=222132ms2132ms

可以看到這些幾乎沒有影響,ii+=11也並沒有單獨的優化,與ii+=22時間並無明顯變化相同


- -ii2158ms2158ms

ii- - : 2167ms2167ms

ii-=1 : 2153ms2153ms

讓我有點喫驚的是,減法幾乎並不慢

還有,+=和-=運算符竟然也不慢,從時間來看甚至還稍微快些,雖然可能是機子誤差,但至少並不比++和- -慢


for(int i=1;i<=1000000000;++i)++k;

2590ms2590ms

for(int i=1;i<=1000000000;++i)++k,++k;

4379ms4379ms

所以執行1e91e9遍加法的速度接近1800ms1800ms

減法速度相近



for(int i=1000000000;i>=1;--i)k=i;

3045ms3045ms

賦值竟然這麼慢

但如果

for(int i=1000000000;i>=1;--i)k=10;

或者

for(int i=1000000000;i>=1;--i)k=k;

2218ms2218ms

優化起了作用


又:ii改成longlonglonglong後空循環幾乎多了一倍時間



再看whilewhile

++ii2355ms2355ms

ii++ : 2378ms2378ms

ii+=1 : 2350ms2350ms

- -ii2365ms2365ms

ii- - : 2368ms2368ms

ii-=1 : 2343ms2343ms

forfor循環總體要慢,大概是whilewhileforfor判斷條件的機制不同吧



乘法

for(int i=1000000000;i>=1;--i)k*=1;

2181ms2181ms

for(int i=1000000000;i>=1;--i)k*=1,k*=1;

2218ms2218ms

出人意料的快,是不是?

但是如果乘的不是11,就會大大降低效率

看起來並沒有做真正的乘法

for(int i=1000000000;i>=1;--i)k*=10;

2605ms2605ms

for(int i=1000000000;i>=1;--i)k*=10,k*=10;

5437ms5437ms

1e91e9遍乘法大概2800ms2800ms,是加法的一倍半

還有一個奇怪的問題,在乘1111的時候,速度慢的有點奇怪,到了3125ms3125ms6265ms6265ms
而乘其他的數,速度會快許多,平均在2500ms2500ms4900ms4900ms左右。

whilewhile測試結果幾乎相同,此處不再放上



除法

for(int i=1000000000;i>=1;--i)k/=1;

2234ms2234ms

for(int i=1000000000;i>=1;--i)k/=1,k/=1;

2312ms2312ms

有了乘法的先例,這個結果不讓人那麼喫驚,優化確實能起作用

for(int i=1000000000;i>=1;--i)k/=10;

4078ms4078ms

for(int i=1000000000;i>=1;--i)k/=10,k/=10;

7746ms7746ms

1e91e9遍除法大概3700ms3700ms,是加法的兩倍還要多



取模

for(int i=1000000000;i>=1;--i)k%=1;

2151ms2151ms

for(int i=1000000000;i>=1;--i)k%=1,k%=1;

2859ms2859ms

優化還是有的

for(int i=1000000000;i>=1;--i)k%=10;

5437ms5437ms

for(int i=1000000000;i>=1;--i)k%=10,k%=10;

11453ms11453ms

1e91e9遍取模大概6100ms6100ms,接近加法的三倍半

取模的慢果然名不虛傳



因爲整理數據的過程實在太過繁瑣,下面只給出結論

以下提到的倍數皆以intint加法比較(1e91e9intint加法接近1800ms1800ms


longlong longlong


1e91e9longlonglonglong加法大概2700ms2700ms,是intint加法的一倍半,與intint乘法相當

減法幾乎與此相同

1e91e9longlonglonglong乘法大概3600ms3600ms,是intint加法的兩倍

1e91e9longlonglonglong除法大概13700ms13700ms,是intint加法的七倍半還要多!

1e91e9longlonglonglong取模大概11800ms11800ms,是intint加法的六倍半多!



shortshort


1e91e9shortshort加法大概1700ms1700ms,比intint加法稍快

減法幾乎與此相同

1e91e9shortshort乘法大概3600ms3600ms,是intint加法的兩倍,與longlonglonglong幾乎相同,比intint乘法還要慢?

1e91e9shortshort除法大概4000ms4000ms,比intint除法也要慢?

1e91e9shortshort取模大概7000ms7000ms,比intint取模慢1000ms1000ms左右?

(可能因爲我的機子是32位?)

還是不要亂用shortshort爲妙



doubledouble


1e91e9doubledouble加法大概4000ms4000ms,是intint加法的兩倍多

減法幾乎與此相同

1e91e9doubledouble乘法大概10500ms10500ms,是intint加法的兩倍多,幾乎與doubledouble加法相同

1e91e9doubledouble除法大概2700ms2700ms,接近intint加法的六倍



longlong doubledouble


1e91e9longdoublelongdouble加法大概9200ms9200ms,是intint加法的五倍多

減法幾乎與此相同

1e91e9longdoublelongdouble乘法大概9200ms9200ms,是intint加法的五倍多,幾乎與longdoublelongdouble加法相同

1e91e9longdoublelongdouble除法大概16100ms16100ms,是intint加法的九倍






後記:可能由於這臺機子是3232位系統,longlong longlonglonglong dopubledopuble都慢的嚇人,等有空再拿6464位測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章