Slide 1

Slide 1 text

YESコマンドは速く なっている @第35回シェル芸勉強会 大阪サテライト Navigate : Space / Arrow Keys | - Menu | - Fullscreen | - Overview | - Blackout | - Speaker | - Help M F O B S ?  1 / 20

Slide 2

Slide 2 text

目次 yesとは 速度指標 yesの比較 いかにして速くなったか [ GitPitch @ github/msr-i386/slide_20180407_yes ]  2 / 20

Slide 3

Slide 3 text

自己紹介 ハンドルネーム: MSR Webブラウザ の作者 Twitter ID: @msr386 Tungsten [ GitPitch @ github/msr-i386/slide_20180407_yes ]  3 / 20

Slide 4

Slide 4 text

yesとは 自分がkillされるまで指定した文字列を繰り返し 出力するコマンド 引数を省略した場合はyが出力され続ける [ GitPitch @ github/msr-i386/slide_20180407_yes ]  4 / 20

Slide 5

Slide 5 text

活用例 続行するのに'y'とEnterキーを押す必要のあるプ ログラム/シェルスクリプトでyを勝手に押して 欲しい場合 負荷試験として シェル芸の足がかりとして [ GitPitch @ github/msr-i386/slide_20180407_yes ]  5 / 20

Slide 6

Slide 6 text

適当にディレクトリを作り、その中で tree したら 次のような出力が得られるようにしてください。 (第33回 シェル芸勉強会 Q1) $ tree . └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ └── ҩ [ GitPitch @ github/msr-i386/slide_20180407_yes ]  6 / 20

Slide 7

Slide 7 text

解答例 $ yes ҩ | head -n 10 | sed -z "s/\n/\//g;s/^/mkdir -p /" | sh [ GitPitch @ github/msr-i386/slide_20180407_yes ]  7 / 20

Slide 8

Slide 8 text

今回の目的 yesコマンドが高速化されたことを確かめる [ GitPitch @ github/msr-i386/slide_20180407_yes ]  8 / 20

Slide 9

Slide 9 text

速度指標 YES PER SECOND [ GitPitch @ github/msr-i386/slide_20180407_yes ]  9 / 20

Slide 10

Slide 10 text

YES PER SECOND 1秒間に何回'y'(+改行コード)を出力することがで きたかを表す 計測には pv コマンド (Pipe Viewer) を使用する debian系なら apt-get で簡単に入手可能 ただし、pvコマンドの結果から単位変換が必要 100 [MiB / s] = 100 / 2 * 1048576 = 52,428,800 [yes / s] "yes per second" ではなく "y per second" ではない か説 [ GitPitch @ github/msr-i386/slide_20180407_yes ]  10 / 20

Slide 11

Slide 11 text

PVコマンド実行例 $ yes | pv > /dev/null 63GiB 0:00:02 [1.88GiB/s] [ <=> ] [ GitPitch @ github/msr-i386/slide_20180407_yes ]  11 / 20

Slide 12

Slide 12 text

計測環境 PC: GPD Pocket OS: Ubuntu 16.04 LTS (Windows Subsystem for Linux) [ GitPitch @ github/msr-i386/slide_20180407_yes ]  12 / 20

Slide 13

Slide 13 text

最初期 1979年1月10日にKen Thompsonによって書かれた コード 実に単純明快 (K&RスタイルのC言語なので今だと 違和感あるかも) 記録: 14,837,350.4 [yes/s] main(argc, argv) char **argv; { for (;;) printf("%s\n", argc>1? argv[1]: "y"); } [ GitPitch @ github/msr-i386/slide_20180407_yes ]  13 / 20

Slide 14

Slide 14 text

NETBSDでの実装 これも非常にシンプル ※一部改行を削除 記録: 14,942,208 [yes/s] int main(int argc, char **argv) { const char *yes; yes = (argc > 1) ? argv[1] : "y"; while(puts(yes) >= 0) continue; return EXIT_FAILURE; } [ GitPitch @ github/msr-i386/slide_20180407_yes ]  14 / 20

Slide 15

Slide 15 text

FREEBSDでの実装 バッファリングで高速化 (2017年7月13日) ※主要部分のみ抜粋、一部改行を削除 ※計測できず int main(int argc, char **argv) { ... ... while ((ret = write(STDOUT_FILENO, exp + (explen - more), if ((more -= ret) == 0) more = explen; err(1, "stdout"); } [ GitPitch @ github/msr-i386/slide_20180407_yes ]  15 / 20

Slide 16

Slide 16 text

GNU COREUTILS バッファリングで高速化 (2015年3月10日) ※主要部分のみ抜粋 記録: 225,443,840 [yes/s] ※8.25 int main (int argc, char **argv) { ... ... /* Repeatedly output the buffer until there is a write error while (full_write (STDOUT_FILENO, buf, bufused) == bufused) continue; error (0, errno, _("standard output")); return EXIT_FAILURE; } [ GitPitch @ github/msr-i386/slide_20180407_yes ]  16 / 20

Slide 17

Slide 17 text

FREEBSD, GNU COREUTILSが高 速な理由 1行ごとに標準出力するのは効率が悪いので、バ ッファリングしてから標準出力する バッファーは1KiB (BUFSIZ @ stdio.h) [ GitPitch @ github/msr-i386/slide_20180407_yes ]  17 / 20

Slide 18

Slide 18 text

参考(1) Unixコマンド”yes”についてのちょっとした話 How is GNU yes so fast? Improve yes' throughput yes: output data more efficiently https://postd.cc/a-little-story-about-the-yes-unix-command/ https://www.reddit.com/r/unix/comments/6gxduc/how_is_g https://github.com/freebsd/freebsd/commit/1d61762ca37c2 https://github.com/coreutils/coreutils/commit/35217221c211 [ GitPitch @ github/msr-i386/slide_20180407_yes ]  18 / 20

Slide 19

Slide 19 text

参考(2) NetBSD - yes.c OpenBSD - yes.c FreeBSD - yes.c GNU coreutils - yes.c http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/yes/yes.c? rev=1.9&content-type=text/x-cvsweb-markup https://github.com/openbsd/src/blob/master/usr.bin/yes/yes https://github.com/freebsd/freebsd/blob/master/usr.bin/yes https://github.com/coreutils/coreutils/blob/master/src/yes.c [ GitPitch @ github/msr-i386/slide_20180407_yes ]  19 / 20

Slide 20

Slide 20 text

おまけ #危険シェル芸 $ yes `yes` [ GitPitch @ github/msr-i386/slide_20180407_yes ]  20 / 20