估算的數據主要依賴於所能獲得的數據和常識,有時還包括實踐而不僅僅是理論。它常常作為一個大問題中的子問題,恰當地估算可以省去精確計算的時間和開銷。在計算機領域,所謂常識的內容很寬泛,比如硬盤的傳輸速度、CPU每秒能執行多少指令、各種數據結構的大小甚至每分鍾錄入的單詞數。有些數據是能夠從各種資料中查得的,但僅僅靠記憶總難免遺漏;如果有經過學習而建立起的系統的知識結構,那便能很方便地把這些常識組織起來,除此以外,還可以靠平時經驗的積累和一些面試題上的啟發了。這里將進行一個收集,隨時更新。
Little定律深入了估算所依賴的法則的細節:總花費等於各個部分的花費再乘以總的部分數,它在計算機系統方面的一些計算中十分有用。
計算機方面的估算問題:
1.硬盤文件讀寫速度的小問題:是否能超過10MB/s?(筆者某次面試中被問到的的一個關於服務器的問題的子問題)
分析:根據以往拷貝文件的經驗,對於不是多個零散小文件的情況,讀寫速度比這個值要快得多,因此做出了肯定的答案。
2.確定一個空循環for(i=0;i<n;i++)在一秒鍾執行的次數n,使其為CPU在1秒鍾內執行總指令數目的一半(《編程之美》第一章的子問題)
分析:先把空循環化為匯編指令:
loop:
mov dx i
inc dx
mov i dx
cmp i n
jl loop
一共5條指令,假設使用的CPU是單核2.4GHz即每秒2.4G個時鍾周期,(常識)現代CPU每個時鍾周期執行兩條以上的代碼,那么一秒鍾可以執行空循環(2 400 000 000 *2)/5 = 960 000 000次。
(為了提高精度而進行降低數量級的優化不再討論)
3.struct node {int i; struct node *p}是否可以將這樣的2 000 000個結點裝入128MB內存的計算機中?(《編程珠璣》7.2性能估計)
分析:為了簡化討論,假定在32位機上int和指針都是32位的,共用了8B,直接計算的結果是只需16MB空間,而《編程珠璣》作者的128MB的計算機通常有85MB空閑,看上去是夠用的。然而使用malloc()為結點分配空間時會額外占用空間(原因:malloc的機制,Linux的malloc()有一個每次分配的最小大小,小於這個值也會分配這么多;struct的對齊),這個值在作者計算機上是40B,導致了一共占用了96MB空間,事實上是不夠用的。
4.運算的實際消耗時間:使用for(i=0;i<n;i++) fa =sqrt(10.0);計算單次sqrt()的運行時間是否准確?(《編程珠璣》7.2性能估計)
實際的單次運算時間可能慢得多,因為sqrt()可能保存了最近參數作為起始值。
(更多待補充……)
估算常用法則:
1.“72法則”:以年利率r%進行投資y年,如果r * y = 72,那么投資差不多會翻倍。
如果以t = (1+r/100)y,並把r代換成72/y,即t = (1+72/(100y))y,進行作圖,會發現這一段t的值都在2附近,符合這條法則。
應用:假設一個指數程序解決n=40的問題需要10s,且n每增加1運行時間就增加12%,那么根據72法則,n每增加6,運行時間就加倍。進一步地,n每增加60,運行時間就為原來的1000倍(210的近似數)。
2.(記憶常識)π秒是一個納世紀。
注:一年有3.155 * 107秒,而π取3.14、納世紀為100年 * 10-9 ,這時兩者的積與這個值近似。
3.Little定律:隊列中物體的平均數量為進入速率與平均停留時間的乘積。
注:顯而易見的法則是,總開銷等於每個開銷乘以單元的個數;而Litte定律描述的是一個動態系統。如果想了解定律的證明,需要隨機過程與排隊論的相關知識。
應用:多用戶系統的響應時間公式,思考時間z的n個用戶登錄到響應時間r的系統,每個用戶周期都為用戶的思考和系統響應,即z+r;作業總數為n,那么對一個時間點來看,平均負荷為n、平均響應時間為z+r,吞吐量為x(每個時間單位處理的作業數),根據Little定律,n = x*(z+r),這樣就可以求解r = n/x -z。
例1:(編程珠璣(續),7.4節)一個計算機系統,包括磁盤、處理器、操作系統和20個思考時間為20秒的終端,通過觀察,它的磁盤每處理一個作業就要處理100個數據請求,而磁盤每秒鍾可以處理25個請求。那么系統的吞吐量和響應時間各為多少?
解答:吞吐量直接計算,為25/100=0.25個作業/秒,響應時間r = 20/0.25 -20 = 60秒。這在流平衡下就是精確解。
例2:(編程珠璣(續),習題7.8)假設一個作業在某機器上執行時間是20秒,該機器一次可能同時執行10個作業,而你的作業是100等待執行的作業中的最后一個,作業以先進先出方式執行。大概需要等多久才能等到作業執行結束?
解答:這里要考慮兩個排隊系統:待執行任務隊列和計算機系統本身。根據Little定律,第二個系統任務輸出率X=L/R,L=10個任務,R=20秒,因此X=0.5個任務/秒。這也是第二個系統的任務到達率。因此最后一個任務會在前99個任務在198秒后完成時進入,再加上20秒的執行時間,總的時間是218秒。
往期回顧:
“珠璣之櫝”系列簡介與索引
位向量/位圖的定義和應用