seq をやったら次はコレしかないじゃない

seq をやったら次はコレしかないじゃない、というわけで、Bashのブレース展開で数字の列を生成します。(まどマギ10周年おめでとうございます。)

色々できるBashのブレース展開ですが、当然のごとく数字の列も生成できます。
「seqコマンドがあるのになぜ?」というのは愚問です。機能があるなら試さずにはいられないのです。

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

seq と違って始まりと終わりを両方必ず指定する必要があります。
なお今回は次のVer.のBashを使ってお届けしています。

$ LANG=C bash --version
GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)

頭に0をつけて桁を揃えるのも出来ます。

$ echo {01..10}
01 02 03 04 05 06 07 08 09 10

そして最近HackerRankのディスカッションページで知ったのですが、3つ目の数値を指定できます。

$ echo {1..10..2}
1 3 5 7 9
$ echo {10..1..-1}
10 9 8 7 6 5 4 3 2 1

だいぶseqコマンドに近いことができる…ように思えるのですが、小数は指定できないあたり(少なくとも私には出来ない)、seqのほうが高機能です。

さて、似たようなことができるなら気になるのが、どちらが速いのか、です。

$ time echo {1..1000000} >/dev/null
real 0m0.556s
user 0m0.548s
sys 0m0.008s
$ time seq 1 1000000 >/dev/null
real 0m0.028s
user 0m0.016s
sys 0m0.011s

ハイ、seqのほうが圧倒的に速かったです。sysがちょっとだけブレース展開のほうが処理が軽いみたいですが、ほぼ誤差と言ってよいかと。

で、前々から感じていたんですけど、ターミナルに出力するのって重い処理なんですね。
(たとえばtar xfとtar xvfの違いとか)

$ time seq 1 1000000
-- snip --
real 0m0.933s
user 0m0.013s
sys 0m0.439s

ターミナルに出力するだけでコレだけ違いが出ます。注目はsysでしょうか。
ちなみに上記、改行を外すだけでも違いが出ます。

$ time seq -s' ' 1 1000000
-- snip --
real 0m0.570s
user 0m0.009s
sys 0m0.067s

ホントはGNU版のtimeコマンドを使ってメモリ使用量なんかも比較したいところですが、今日はもう遅いのでこのくらいで。(ホントはGNU版timeコマンドを使いこなせてないので後日。)