Performance

指定格式字元串時 Seq 性能下降

  • March 30, 2016

與我嘗試過的任何可能的格式相比,在不指定格式字元串的情況下 執行 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

這裡發生了什麼?明確提供格式字元串時是否可以重現性能?

這是相當的觀察,但它實際上是有道理的。這是原始碼: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

至於為什麼格式化需要更長的時間(1 分鐘時間用 1e8 而不是 1e9),請注意 53/10^8 秒 = 530 納秒。因此,平均而言,格式程式碼(在列印之前必須在每個數字上執行)會為每個列印數字增加大約 530 納秒。考慮到格式化中涉及的所有分支和復雜邏輯,這也是有道理的。

引用自:https://unix.stackexchange.com/questions/272968