官术网_书友最值得收藏!

指針與數組鏈表的比較

一個常見的編程問題:遍歷同樣大小的數組和鏈表,哪個比較快?如果按照某些教科書上的分析方法,你會得出結論,這二者一樣快,因為時間復雜度都是O(n)。但是在實踐中,這二者卻有極大的差異。通過下面的分析你會發現,其實數組比鏈表要快很多。

首先介紹一個概念:memory hierarchy(存儲層次結構),計算機中存在多種不同的存儲器,各存儲器的平均存取速度相差很大,如表1.1所示。

表1.1

各級別的存儲器速度差異非常大,CPU寄存器速度是內存速度的100倍!這就是為什么CPU生產廠家發明了CPU緩存的原因。而這個CPU緩存,就是數組鏈表和指針鏈表區別的關鍵所在。

CPU緩存會把一片連續的內存空間讀入,因為數組結構是連續的內存地址,所以數組全部或者部分元素被連續存在CPU緩存里面,平均讀取每個元素的時間只要3個CPU時鐘周期。而鏈表的結點是分散在堆空間里面的,這時候CPU緩存幫不上忙,只能是去讀取內存,平均讀取時間需要100個CPU時鐘周期。這樣算下來,數組訪問的速度比鏈表快33倍!(以上皆為理論數字,具體的數字視CPU型號及環境不同而略有差異)

因此,程序中盡量使用連續的數據結構,這樣可以充分發揮CPU緩存的威力。這種對緩存友好的算法稱為Cache-oblivious algorithm,有興趣可以參考相關資料。再舉一個簡單例子,如表1.2所示。

表1.2

雖然兩者執行結果一樣,算法復雜度也一樣,但是你會發現第二種寫法要快很多。

總結一下,各種存儲器的速度差異很大,在編程中絕對有必要考慮這個因素。比如,內存速度比硬盤快1萬倍,所以程序中應該盡量避免頻繁的硬盤讀寫;CPU緩存比內存快幾十倍,在程序中盡量多加利用。

為了驗證理論的正確性,可以通過隨機化讀寫的測試來比較兩者的差異。

測試數據如下:

data1 100000次隨機插入刪除操作,數據在[0,32767]之間;(刪除操作較少)

data2 100000次隨機插入刪除操作,數據在[0,256]之間;(刪除較多)

data3 100000次隨機插入刪除操作,數據在[0,32]之間;(刪除比較頻繁)

data4 1000次隨機插入刪除操作,數據在[0,32767]之間;

data5 1000次隨機插入刪除操作,數據在[0,256]之間;

data6 1000次隨機插入刪除操作,數據在[0,32]之間;

data7 10次隨機插入刪除操作,數據在[0,32767]之間;

data8 10次隨機插入刪除操作,數據在[0,25 6]之間;

data9 10次隨機插入刪除操作,數據在[0,32]之間;

Cena測試結果如圖1.3所示。

圖1.3

以上測試在Thinkpad T60:2.0GHz Dou CPU,1GB RAM windows XP SP3系統環境下進行。

主站蜘蛛池模板: 盘山县| 湄潭县| 铜山县| 汪清县| 嘉荫县| 崇左市| 咸阳市| 沈阳市| 黎平县| 象山县| 宁陵县| 乾安县| 甘肃省| 佛学| 石景山区| 阿荣旗| 五原县| 岗巴县| 丽江市| 彭阳县| 商南县| 梅州市| 商水县| 河东区| 社旗县| 大洼县| 神农架林区| 青阳县| 大同市| 平塘县| 沈阳市| 灌阳县| 苗栗县| 县级市| 申扎县| 泗水县| 长兴县| 新闻| 平远县| 原平市| 扶风县|