指定格式字符串时 Seq 性能受到影响

指定格式字符串时 Seq 性能受到影响

运行序列(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 纳秒。考虑到格式化涉及的所有分支和复杂逻辑,这也是有道理的。

相关内容