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