python存取dict

強殖裝甲凱普發表於2020-11-29

文章目錄

前言

這裡的方法同樣可以儲存陣列或者別的陣列,這裡主要以字典為主要物件。

正文

pickle,numpy都可以進行檔案持久化。

編寫以下程式碼測試效能

import numpy as np
import pickle as pkl
import time

a = {
    'a': np.random.randn(8000, 2, 30, 160),
    'b': np.random.randn(8000, 2, 30, 160),
    'c': np.random.randn(8000, 2, 30, 160),
    'd': np.random.randn(8000, 2, 30, 160),
    'e': np.random.randn(8000, 2, 30, 160),
}

time_a = time.time()

np.save('data.npy', a)

time_b = time.time()

np.save('data.npy', a)

time_c = time.time()

print('numpy 儲存耗時:{}'.format(time_b-time_a))
print('numpy 讀取耗時:{}'.format(time_c-time_b))

time_a = time.time()

with open('data.pkl', 'wb') as f:
    pkl.dump(a, f, protocol=pkl.HIGHEST_PROTOCOL)

time_b = time.time()

with open('data.pkl', 'rb') as f:
    a = pkl.load(f)

time_c = time.time()

print('pickle 儲存耗時:{}'.format(time_b-time_a))
print('pickle 讀取耗時:{}'.format(time_c-time_b))

執行結果為:

numpy 儲存耗時:3.349184274673462
numpy 讀取耗時:4.978081941604614
pickle 儲存耗時:6.070725202560425
pickle 讀取耗時:2.0159759521484375

檔案大小比較,首先是numpy的大小為:
在這裡插入圖片描述
pickle大小為:
在這裡插入圖片描述

pickle的儲存效能比numpy慢兩倍,讀取快兩倍。最後儲存的檔案大小一樣。

然後探究儲存後的檔案大小與存取效能之間的關係,首先更改程式碼為:

import numpy as np
import pickle as pkl
import time
import matplotlib.pyplot as plt
import os

x = []

np_save = []
np_load = []

pkl_save = []
pkl_load = []

s = time.time()

for i in range(25):
    size = 1000 * (i + 1)

    a = {
        'a': np.random.randn(size, 2, 30, 160),
        'b': np.random.randn(size, 30, 160),
        'c': np.random.randn(size, 2, 30, 160),
        'd': np.random.randn(size, 2, 30, 160),
        'e': np.random.randn(size, 2, 30, 160),
    }

    time_a = time.time()

    np.save('data.npy', a)

    time_b = time.time()

    np.save('data.npy', a)

    time_c = time.time()
    
    np_save.append(time_b-time_a)
    np_load.append(time_c-time_b)

    time_a = time.time()

    with open('data.pkl', 'wb') as f:
        pkl.dump(a, f, protocol=pkl.HIGHEST_PROTOCOL)

    time_b = time.time()

    with open('data.pkl', 'rb') as f:
        a = pkl.load(f)

    time_c = time.time()

    pkl_save.append(time_b-time_a)
    pkl_load.append(time_c-time_b)

    x.append(os.path.getsize('data.npy') / (1024. * 1024. * 1024.))

plt.figure()

ax1 = plt.subplot(211)
ax1.plot(x, np_save, label='numpy')
ax1.plot(x, pkl_save, label='pickle')
plt.xlabel('size (G)')
plt.ylabel('save time (s)')
plt.legend()

ax2 = plt.subplot(212)
ax2.plot(x, np_load, label='numpy')
ax2.plot(x, pkl_load, label='pickle')
plt.xlabel('size (G)')
plt.ylabel('load time (s)')
plt.legend()

print(time.time()-s)

plt.show()

結果為:
在這裡插入圖片描述
可以看出,pickle在讀取上一直佔優,即使檔案較大,讀取時間上升也較為平緩。在儲存上兩者拉不開明顯差距,但一般來看numpy是有優勢的,比如我們不管後面的劇烈上升,而是看較為平緩的一段:
在這裡插入圖片描述
可以看出numpy在讀取上,6g以下是明顯佔優的,6g以上兩者會難分難解

在這裡插入圖片描述
觀察發現,大檔案還是使用pickle比較好

相關文章