- 算法競賽寶典(第三部):基礎數據結構
- 張新華
- 948字
- 2021-03-19 16:58:15
指針與數組鏈表的比較
一個常見的編程問題:遍歷同樣大小的數組和鏈表,哪個比較快?如果按照某些教科書上的分析方法,你會得出結論,這二者一樣快,因為時間復雜度都是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系統環境下進行。
- Google Flutter Mobile Development Quick Start Guide
- 基于粒計算模型的圖像處理
- Visual C++程序設計學習筆記
- Delphi程序設計基礎:教程、實驗、習題
- 樂學Web編程:網站制作不神秘
- 深入淺出Spring Boot 2.x
- Web全棧工程師的自我修養
- 教孩子學編程:C++入門圖解
- 零基礎學Java程序設計
- Create React App 2 Quick Start Guide
- Processing創意編程指南
- Creating Data Stories with Tableau Public
- OpenStack Networking Essentials
- Zabbix Performance Tuning
- Tableau Desktop可視化高級應用