[英]Most efficient way to calculate CRC16 in Python
我需要在循環內多次計算二進制數的CRC16。 我使用了以下方法
import numpy as np
import binascii
#I have just filled the array with random numbers
#These arrays are loaded from a file
array1=np.random.randint(0,511, size=100000)
array2=np.random.randint(0,511, size=100000)
#...
#This goes on to till say array100
#Now calculate crc of each row in a loop
for j in range(100000):
crc=0xffff
#Convert the number to binary 16 bit format
temp_bin=np.binary_repr(array1[j], 16)
crc=binascii.crc_hqx(chr(int(temp_bin[0:8],2)), crc)
crc=binascii.crc_hqx(chr(int(temp_bin[8:16],2)), crc)
#Similarly for array2
temp_bin=np.binary_repr(array2[j], 16)
crc=binascii.crc_hqx(chr(int(temp_bin[0:8],2)), crc)
crc=binascii.crc_hqx(chr(int(temp_bin[8:16],2)), crc)
#...
#This goes on till array100
盡管此方法可以完美運行,但速度非常慢。 分析時,我發現將每個數字轉換為二進制是代碼中的主要瓶頸。
總時間:10.9712 s
文件:speedup.py
功能:第7行的abc
行_____命中____時間____每次命中____%時間____行內容
7 @profile
8 def abc():
9 #I have just filled the array with random numbers
10 #Thse arrays are loaded from a file
11 1 3269.0 3269.0 0.0 array1=np.random.randint(0,511, size=100000)
12 1 3206.0 3206.0 0.0 array2=np.random.randint(0,511, size=100000)
13 #...
14 #This goes on to till say array100
15 #Now calculate crc of each row in a loop
16 100001 237461.0 2.4 2.2 for j in range(100000):
17 100000 199887.0 2.0 1.8 crc=0xffff
18 #Convert the number to binary 16 bit format
19 100000 3436116.0 34.4 31.3 temp_bin=np.binary_repr(array1[j], 16)
20 100000 1039049.0 10.4 9.5 crc=binascii.crc_hqx(chr(int(temp_bin[0:8],2)), crc)
21 100000 793751.0 7.9 7.2 crc=binascii.crc_hqx(chr(int(temp_bin[8:16],2)), crc)
22 ##Similarly for array2
23 100000 3423862.0 34.2 31.2 temp_bin=np.binary_repr(array2[j], 16)
24 100000 991331.0 9.9 9.0 crc=binascii.crc_hqx(chr(int(temp_bin[0:8],2)), crc)
25 100000 843271.0 8.4 7.7 crc=binascii.crc_hqx(chr(int(temp_bin[8:16],2)), crc)
我無法提出一種避免這種情況的替代解決方案。 那么,有沒有更有效,更Python化的方法將數字轉換為二進制或完成全部操作?
查看您的代碼,您可能可以繞過將整數發送到字符串然后返回的過程。 尤其是因為您要將8位二進制數組填充為零的16位,因此只能將其再次分成兩半。 相反,請嘗試:
zb = np.zeros(1, dtype=np.uint8)[0].tobytes()
for j in range(100000):
crc=0xffff
tmp_data = array1[j].tobytes()
crc=binascii.crc_hqx(zb, crc)
crc=binascii.crc_hqx(tmp_data, crc)
tmp_data = array2[j].tobytes()
crc=binascii.crc_hqx(zb, crc)
crc=binascii.crc_hqx(tmp_data, crc)
終於我找到了一種更快的方法。 不必首先將數字轉換為二進制,我們可以巧妙地使用位運算符。 此實現速度大約是三次。
import numpy as np
import binascii
#I have just filled the array with random numbers
#These arrays are loaded from a file
array1=np.random.randint(0,511, size=100000)
array2=np.random.randint(0,511, size=100000)
#...
#This goes on to till say array100
#Now calculate crc of each row in a loop
for j in range(100000):
crc=0xffff
#Convert the number to binary 16 bit format
crc=binascii.crc_hqx(chr(array1[j] >> 8), crc)
crc=binascii.crc_hqx(chr(array1[j] & 255), crc)
#Similarly for array2
crc=binascii.crc_hqx(chr(array2[j] >> 8), crc)
crc=binascii.crc_hqx(chr(array2[j] & 255), crc)
#...
#This goes on till array100
使用線路分析器進行的比較表明,這種計算CRC的方法快了三倍:
總時間:2.66351 s
檔案:speedup1.py
功能:第4行的abc
4 @profile
5 def abc():
6 #I have just filled the array with random numbers
7 #These arrays are loaded from a file
8 1 1204.0 1204.0 0.0 array1=np.random.randint(0,511, size=100000)
9 1 1207.0 1207.0 0.0 array2=np.random.randint(0,511, size=100000)
10 #...
11 #This goes on to till say array100
12 #Now calculate crc of each row in a loop
13 100001 93020.0 0.9 3.5 for j in range(100000):
14 100000 83277.0 0.8 3.1 crc=0xffff
15 #Convert the number to binary 16 bit format(This is the old method)
16 100000 1280059.0 12.8 48.1 temp_bin=np.binary_repr(array1[j], 16)
17 100000 351190.0 3.5 13.2 crc=binascii.crc_hqx(chr(array1[j] >> 8), crc)
18 100000 299711.0 3.0 11.3 crc=binascii.crc_hqx(chr(array1[j] & 255), crc)
19 #Similarly for array2(This is the new method using bit operators)
20 100000 276893.0 2.8 10.4 crc=binascii.crc_hqx(chr(array2[j] >> 8), crc)
21 100000 276946.0 2.8 10.4 crc=binascii.crc_hqx(chr(array2[j] & 255), crc)
使用crcmod 。 它將為指定的CRC生成高效代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.