次のコードを高速化しようとしています。文字列のリストが与えられた場合str_list
、文字列を数値 ( unpack
) に変換し、この数値をネストされたリストの正しい位置に割り当てようとしていますdata
。の寸法data
はおおよそdata[4][20][1024]
です。残念ながら、この関数は非常にゆっくりと実行されます。コードは次のとおりです。
for abs_idx in range(nbr_elements):
# get string
this_element = str_list[abs_idx]
# convert into number
this_element = unpack('d', this_element)[0]
# calculate the buffer number
buffer_nbr = abs_idx / NBR_DATA_POINTS_PER_BUFFER_INT
# calculate the position inside the buffer
index_in_buffer = abs_idx % NBR_DATA_POINTS_PER_BUFFER_INT
# write data into correct position
data[file_idx][buffer_nbr][index_in_buffer] = this_element
さらに遅い次の代替ソリューションも試しました。
# convert each string into a number
unpacked_values = [unpack('d', str_list[j])[0] for j in range(nbr_elements)]
for abs_idx in range(nbr_elements):
# calculate the buffer number
buffer_nbr = abs_idx / NBR_DATA_POINTS_PER_BUFFER_INT
# calculate the position inside the buffer
index_in_buffer = abs_idx % NBR_DATA_POINTS_PER_BUFFER_INT
# write data into correct position
data[file_idx][buffer_nbr][index_in_buffer] = unpacked_values[abs_idx]
驚いたことに、次の実装が最も遅いです (最速だと思っていました)。
# convert each string into a number
unpacked_values = [unpack('d', str_list[j])[0] for j in range(nbr_elements)]
# calculate all buffer numbers at once
buffer_ids = np.arange(nbr_elements) / NBR_DATA_POINTS_PER_BUFFER_INT
# calculate all positions inside the buffer at once
index_in_buffer_id = np.arange(nbr_elements) % NBR_DATA_POINTS_PER_BUFFER_INT
for abs_idx in range(nbr_elements):
data[file_idx][buffer_ids[abs_idx]][index_in_buffer_id[abs_idx]] = unpacked_values[abs_idx]
連続する実装のパフォーマンスが悪いのはなぜですか? 個々のボトルネックはどこにありますか? また、最初のコードを高速化するにはどうすればよいですか?
編集:私のプロファイリング テストから、次の 2 つのステップがボトルネックです: 実行unpack
と への値の割り当てdata
。これらのステップをスピードアップする方法はわかりません。
EDIT2:unpack
文字列が16進数であるため、使用する必要があります。
EDIT3: values = unpack("d" * n, "".join(str_list))
unpack が遅いという問題を解決します。それでも、トリプル (元の) またはダブル (変更された) ネストされたループを使用したデータへの代入は、50% の時間を消費します。この時間を短縮する方法はありますか?