pyserialでシリアル通信するためのリストデータをバイト文字列に変換する処理が、
どうも遅い感じがしたので調べた結果をメモ。
###今までの実装
特に何も考えず、とりあえずバイト文字列が作れればいいやという単純なもの。
data = [ _ for _ in xrange(0, 10) ]
byte_str = "".join([chr(x) for x in send_list])
# byte_str => '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t'
###処理速度検証
別の実装方法を模索していた所、参考リンクにあるstackoverflowの記事に書かれていた
処理をテストしてみる事にした。
なお、pythonのバージョンは2系です。
import time
import array
import struct
def main():
# 計測用メソッド
def measure_time(data, func):
post = time.time()
for _ in xrange(1000000):
func(data)
t = time.time() - post
return t
# バイト文字列変換メソッド(処理結果は全パターン同じです)
bytearray_pattern = lambda x : str(bytearray(x)) # パターン1
array_pattern = lambda x : array.array(b'B', x).tostring() # パターン2
struct_pattern = lambda x : struct.pack(b'B' * len(x), *x) # パターン3
join_pattern = lambda x : "".join([chr(_) for _ in x]) # パターン4(今までの処理)
# テスト用リストデータ
small_data = [ _ for _ in xrange(0,10) ] # len=10
huge_data = [ _ for _ in xrange(0,256) ] # len=256
# メイン処理
proc_time = measure_time(small_data, bytearray_pattern) # proc_time:1.18099999428
proc_time = measure_time(small_data, array_pattern) # proc_time:0.874000072479
proc_time = measure_time(small_data, struct_pattern) # proc_time:0.784999847412
proc_time = measure_time(small_data, join_pattern) # proc_time:1.72000002861
proc_time = measure_time(huge_data, bytearray_pattern) # proc_time:5.57999992371
proc_time = measure_time(huge_data, array_pattern) # proc_time:11.3169999123
proc_time = measure_time(huge_data, struct_pattern) # proc_time:11.0810000896
proc_time = measure_time(huge_data, join_pattern) # proc_time:32.9349999428
main()
###結果
送信するデータ数が多い場合は、パターン1のstr(bytearray(list)
を使うのが良さそう。
また、データ数が少ない場合は、パターン2やパターン3のほうが速くなる場合もある模様。(誤差っぽいですが)
とりあえず確実に言える事は「パターン4だけは無い」という事ですかね・・・(反省)
###参考リンク
http://stackoverflow.com/questions/3470398/list-of-integers-into-string-byte-array-python