一度に1バイトの読み取りと書き込みは非常に遅くなります。f.read
およびを呼び出すたびにファイルからより多くのデータを読み取るだけで、コードを約45倍高速化できますf.write
。
|------------------+--------------------|
| using_loop_20480 | 8.34 msec per loop |
| using_loop_8 | 354 msec per loop |
|------------------+--------------------|
using_loop
この投稿の下部に表示されているコードです。using_loop_20480
チャンクサイズ=1024*20のコードです。これは、一度に20480バイトがファイルから読み取られることを意味します。using_loop_1
チャンクサイズ=1の同じコードです。
についてcount % 8 is 0
:is
数値の比較には使用しないでください。==
代わりに使用してください。is
間違った結果をもたらす可能性のあるいくつかの例を次に示します(投稿したコードにはないかもしれませんが、一般的に、is
ここでは適切ではありません)。
In [5]: 1L is 1
Out[5]: False
In [6]: 1L == 1
Out[6]: True
In [7]: 0.0 is 0
Out[7]: False
In [8]: 0.0 == 0
Out[8]: True
それ以外の
struct.pack('{n}B'.format(n = len(bytes)), *bytes)
あなたが使うことができます
bytearray(bytes)
タイピングが少ないだけでなく、少し速くなります。
|------------------------------+--------------------|
| using_loop_20480 | 8.34 msec per loop |
| using_loop_with_struct_20480 | 8.59 msec per loop |
|------------------------------+--------------------|
バイト配列は、データを文字列と数列と見なす間のギャップを埋めるため、このジョブに適しています。
In [16]: bytearray([97,98,99])
Out[16]: bytearray(b'abc')
In [17]: print(bytearray([97,98,99]))
abc
上記のようにbytearray(bytes)
、バイト配列に一連のint(in)を渡すことでバイト配列を定義でき
range(256)
、文字列であるかのように書き出すことができますg.write(bytearray(bytes))
。
def using_loop(output, chunksize):
with open(filename, 'r') as f, open(output, 'wb') as g:
while True:
chunk = f.read(chunksize)
if chunk == '':
break
bytes = [int(chunk[i:i+8], 2)
for i in range(0, len(chunk), 8)]
g.write(bytearray(bytes))
チャンクサイズが8の倍数であることを確認してください。
これは、テーブルの作成に使用したコードです。prettytableもこれと同様のことを行うことに注意してください。私のハックではなく、それらのコードを使用することをお勧めします:table.py
これは、コードの時間を計るために使用したモジュールutils_timeit.pyです。(table.pyを使用します)。
そして、これが私が時間を計るために使用したコードusing_loop
(および他のバリアント)です:timeit_bytearray_vs_struct.py