运行序列(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
至于为什么格式化需要更长的时间(使用 1e8 而不是 1e9 需要 1 分钟),请注意 53/10^8 秒 = 530 纳秒。因此,平均而言,格式代码(在打印之前必须在每个数字上运行)会为每个打印数字增加约 530 纳秒。考虑到格式化涉及的所有分支和复杂逻辑,这也是有道理的。