簡體   English   中英

用Python計算CRC16的最有效方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM