フォーマット文字列を指定したときに影響を受けるシーケンスのパフォーマンス

フォーマット文字列を指定したときに影響を受けるシーケンスのパフォーマンス

実行シーケンス(GNU coreutils 8.21)これは、私が試した可能性のあるフォーマットと比較してフォーマット文字列を指定することなく非常に迅速に実行されます。

$ time seq 1e8 > /dev/null
seq 1e8 > /dev/null
0.68s user 0.02s system 99% cpu 0.703 total

$ time seq -f '%1.f' 1e8 > /dev/null                                                                                                                                                                                                          
seq -f '%1.f' 1e8 > /dev/null
53.82s user 0.03s system 99% cpu 53.875 total

ここで何が起こっているのでしょうか?フォーマット文字列を明示的に指定するとパフォーマンスが再現されますか?

ベストアンサー1

これは非常に観察的なものですが、実際には意味があります。ソースコードは次のとおりです。http://code.metager.de/source/xref/gnu/coreutils/src/seq.c

seq_fastまず、関数と呼び出しの前のコメントに注意してください。

608  /* If the following hold:
609     - no format string, [FIXME: relax this, eventually]
610     - integer start (or no start)
611     - integer end
612     - increment == 1 or not specified [FIXME: relax this, eventually]
613     then use the much more efficient integer-only code.  */

これらの条件が満たされると、より良いアルゴリズムがあることがわかります。実際に増分を追加すると、以下を使用するのではなく同じprint_numbers動作が遅くなりますseq_fast

time seq  1e9 > /dev/null 
seq 1e9 > /dev/null  4.68s user 0.09s system 99% cpu 4.770 total


time seq  1 7 1e9 > /dev/null
seq 1 7 1e9 > /dev/null  56.78s user 0.02s system 99% cpu 56.801 total

フォーマットに時間がかかる理由(1e9ではなく1e8を使用している場合は1分)は53/10^8秒= 530ナノ秒です。したがって、平均してフォーマットコード(印刷する前に各番号に対して実行する必要があります)は、印刷された各番号に約530ナノ秒を追加します。これは、書式設定に関連するすべての分岐と複雑なロジックを考慮すると意味があります。

おすすめ記事