python優化——善用numpy api

原來的代碼是這樣的:

# write shape first
s = frame.shape # frame是用cv2從視頻中讀出來的圖片,類型:numpy.ndarray
buf = [0 for i in range(s[0] * s[1] + 8)] # 創建一個buffer
self.int_bytes(s[0], buf, 0, 4) # 把圖片寬度寫入buffer
self.int_bytes(s[1], buf, 4, 4) # 把圖片高度寫入buffer
count = 8
# write data
for i in range(s[0]):
	for j in range(s[1]):
		buf[count] = frame[i][j] # 把frame從二維數組轉成一維數組,寫入buffer
		count += 1
buf = bytes(buf) # 把buffer從整型數組轉成bytes
self.write(buf) # write這個函數通過ctypes綁定到了一個動態鏈接庫上

跑了一下發現這段代碼及其耗時,我覺得主要問題在於創建buffer和把frame拷貝到buffer這兩個地方,於是嘗試用numpy的api來優化一下:

s = frame.shape
# write shape
buf = bytearray(8)
self.int_bytes(s[0], buf, 0, 4)
self.int_bytes(s[1], buf, 4, 4)
self.write(buf)
# write data
data = frame.reshape(s[0] * s[1]).tostring()
self.write(data)

不僅簡潔多了,性能也指數級上升!
首先我把buf從整型數組換成了bytearray(可以修改的bytes),並且只用它存儲圖片大小信息——8個字節。
其次把frame從二維數組轉成一維數組我使用了reshape這個api,我覺得reshape操作是不會修改數據本身、只會修改數組的元信息(如果我實現我會這麼做),所以免去了第一個版本中的拷貝操作。
最後,在同樣的場景下測試,第一個版本跑一次要1秒多,第二個版本只要1毫秒左右。Nice!

發佈了36 篇原創文章 · 獲贊 13 · 訪問量 6505
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章