実行シーケンス(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ナノ秒を追加します。これは、書式設定に関連するすべての分岐と複雑なロジックを考慮すると意味があります。