用記憶體管理講解為何 python 的 list 那麼慢

用記憶體管理講解為何 python 的 list 那麼慢張憲騰BlockedUnblockFollowFollowingApr 12Python 雖然好用,但也經常被別人詬病他的執行速度非常慢,但為什麼慢?我們可以用什麼方式解決?這邊想跟大家分享一些 記憶體的觀念,讓大家知道用 Python 也是可以用得很聰明得。這邊你會看到程式是如何跟記憶體進行合作的numpy.

array 跟 list 的差別,為什麼我們都會建議使用 array 進行運算先說說一些記憶體的小常識吧當你在 python 內執行 a=5 的時候,你知道電腦做了什麼事嗎?python 會去跟電腦要一塊記憶體,把 5 存在這塊記憶體內,並且把記憶體位置記下(如 0x001 ),這時他們會把 a 和另一個記憶體位置記在一個 Mapping Table 上,如下圖:這時當你之後再呼叫 a 這個變數的時候,程式就會知道要到0x001去找裡面儲存的值(回應 5)這邊講完了記憶體的小概念,下面就要更接近主題了。在進行資料處理時,我們極力推薦 numpy.

array 而不是 python 原生的 list大家都說 Python 在處理資料的速度慢很多,當然就有大神發現在極度方便的 Python 需要一個套件可以加快他的速度,此時 numpy 就出來的,裡面有一個非常重要的觀念就是 numpy.

arrayarray 跟 list 差在哪裡呢?為什麼 array 會跑得比 list 還要快呢?list 的運作原理這邊先講 list,python 的 list 真的很好用,他可以用 append自動把元素加入list 裡面,而在一個 list 裡面也可以儲存不同型態的資料,例如:a_list = [3, [‘Sam’, ‘Hands’] ,( [‘Brian’],42,’Python’)],我們如果要加入資料只要 a_list.

append(33) 即可但他在記憶體內是怎麼實作的呢?首先記憶體內會要 a_list 數量的記憶體空間,去把 a_list[0], a_list[1], … 的資料存進去接著程式再去要一塊空間生成一個空的 list 並存入這些指向元素的 pointer ,產生一個記憶體位置,EX: a_list = 0x002 ,並記錄在 Mapping Table 內。此時你的 a_list[0] 可能存入的是 0x003 , 然後他指向的記憶體位置內 3 這個值,所以當我們寫出 print(a_list[0])時,他會先指向 a_list 的位置,把那個存入很多 pointer 的 list 拿出來,之後再找到第 0 個存入的位置,再去那塊記憶體位置把 3 拿出來,印在你的電腦上。透過以上的解釋,這也就是為什麼我們的 list 內可以儲存許多不同型態的值,而且也都可以自由地新增與刪除了。array 的運作原理那 array 呢? array 是過往底層語言會用的記憶體操作方法,他的效益就是比較快,而為什麼比較快呢?如以下解釋當我們今天宣告 a_array = np.

array([[1,2,3],[4,5,6]]),電腦做了什麼事呢?程式會先跟電腦要一大塊記憶體,必須是連續且不能斷裂的,這時這他就將這個大 array 就丟進這個大塊記憶體內,並且各自找到一個空間,去記錄下來。之後便在 Mapping Table 內去紀錄 a_array 在哪個記憶體位置,因為上面做過很多次了,這邊就不在重複了。這樣為什麼比較快呢?想一想你今天要去找你同學,所以你到了某一家敲門問他說:「你知不知道張憲騰住哪啊?」一個跟你說就住旁邊的旁邊,一個跟你說他住在三條街右轉的第二間,哪個比較快呢?更不用說假如現在是巢狀的結構,那肯定又更慢了。但他也有一些缺點,例如 numpy.

array 不能夠自由增減元素,裡面也不能存取不同型態的資料(否則整個資料型態會以儲存最大記憶體的型態存取),在操作上會很不方便。但我用 python 就是要方便啊!有沒有折衷的方案,有的,這時你就不得不讚嘆前人的技術,他們開發出一個神之套件 — pandas這邊留個伏筆,若是 claps 的數量高於 300,代表文章有人想看嗚嗚這樣下次會跟大家說 pandas 是如何運用內部套件 blockManager 結合 numpy.

array 跟方便性的。ps.

這邊因為是一個科普文章,所以在記憶體內很多的觀念都是打到為止,例如說:a = 5 他其實是記住儲存 5 的記憶體位置的第一位(一個int8 佔據 1 byte) ,希望高手看到不要太苛責。.

. More details

Leave a Reply