方案制定
如何最高效率的將一個正整數(shù)擴大一千倍?
當這個問題被拋給人腦的時候,接受過優(yōu)秀的九年義務教育的我們稍加思索就能給出一個調(diào)皮而又不失大師風范的答案:添三個零就行了~
但是當這個問題交給程序員用代碼解決的時候,問題就要從編程的角度去考慮。我作為phper
第一時間想到的方案分別是
-
方案1:在數(shù)字末尾粘連字符串 “000”
-
方案2:將原數(shù)字簡單的乘以 1000
當我把這個問題丟給我的朋友的時候,他告訴我:
方案1肯定不行!你應該采用方案2,但是如果你足夠雞賊的話,你應該采用正整數(shù) X 1024 - 正整數(shù) X 24
!
因為計算機是二進制,當你告訴他要乘以1000的時候,他會進行正整數(shù) X 512 + 正整數(shù) X 256 + 正整數(shù) X 128 + 正整數(shù) X 128 + 正整數(shù) X 64 + 正整數(shù) X 32 + 正整數(shù) X 8
,一直累加到湊齊 正整數(shù)的 1000 倍 為止。而運算2的10次方
要比那一串加號更快接近結(jié)果。
【推薦學習:PHP視頻教程】
實踐出真知
大佬的這段話很快打動了我。為了踐行大佬的真知,證明大佬的闡述對我猶如醍醐灌頂般點醒夢中人,我迅速寫出了一小段方法,將一個隨機正整數(shù)擴大1000倍的算法用三種不同的方法分別跑 一千萬次,查看各個方法運行的效率(使用框架:laravel)
// 圖表內(nèi)容 $headers = ['次數(shù)', '方案1:拼接法', '方案2:乘1000', '方案3:乘以 1024']; $data = [ [0=>'第一次'], [0=>'第二次'], [0=>'第三次'] ]; // 每個方法執(zhí)行三次 for ($count = 0; $count < 3; $count ++) { // 生成變量名 : plan1start1 $start = Carbon::now()->getPreciseTimestamp(); for ($i = 0; $i < 10000000; $i ++) { $integer = rand(1, 999); $result = (int)($integer . '000'); } $end = Carbon::now()->getPreciseTimestamp(); $data[$count][] = ($end - $start)/1000000 . '秒'; } for ($count = 0; $count < 3; $count ++) { $start = Carbon::now()->getPreciseTimestamp(); for ($i = 0; $i < 10000000; $i ++) { $integer = rand(1, 999); $result = $integer * 1000; } $end = Carbon::now()->getPreciseTimestamp(); $data[$count][] = ($end - $start)/1000000 . '秒'; } for ($count = 0; $count < 3; $count ++) { $start = Carbon::now()->getPreciseTimestamp(); for ($i = 0; $i < 10000000; $i ++) { $integer = rand(1, 999); $result = $integer * 1024 - $integer * 24; } $end = Carbon::now()->getPreciseTimestamp(); $data[$count][] = ($end - $start)/1000000 . '秒'; } $this->table($headers, $data);
將這段代碼運行多次后均得到一個較為穩(wěn)定的結(jié)果:
看到這個結(jié)果,大大的疑問重新占領(lǐng)了我小小的腦瓜。乘以 1024 再減去 乘以 24
反而比直接乘以 1000
慢一些。當我拿著這個結(jié)果去尋找大佬解決疑惑時,得到了他這樣的回答:
平時工作不夠多是不是?還有空做這種試驗?
對試驗結(jié)果的思考
暗戳戳鄙夷他一把,順便把他在我心中的地位從大佬
降格為我的某個不愿透露姓名的普通朋友
。我繼續(xù)了對這件事請的思考。
在正整數(shù)后面拼接字符串 ‘000’,要把這個正整數(shù)轉(zhuǎn)換為字符串,然后拼接字符串 ‘000’,之后再轉(zhuǎn)回正整數(shù)。計算的復雜程度遠超正整數(shù)的直接計算,時間上明顯劣于后者,這點經(jīng)過驗證也毋庸置疑。
但是我的某個不愿透露姓名的豆豆同學對二進制
計算模式解釋的同樣頭頭是道。我學習的是解釋型語言 php
,這意味著有一群對代碼理解達到骨灰級的玩家在我看不到的地方對php
進行了大量的算法優(yōu)化。而豆豆同學學習的是編譯型語言 C++
。是不是這種解釋型語言的不同點,導致了本次運算結(jié)果的不同?