Upgrade to Pro — share decks privately, control downloads, hide ads and more …

yes command faster

MSR
April 07, 2018

yes command faster

yesコマンドは速くなっている
※絵文字が正常に表示されていません。完全版は https://gitpitch.com/msr-i386/slide_20180407_yes/ まで。

MSR

April 07, 2018
Tweet

More Decks by MSR

Other Decks in Technology

Transcript

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

    1 / 20

    View Slide

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

    2 / 20

    View Slide

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

    3 / 20

    View Slide

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

    4 / 20

    View Slide

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

    5 / 20

    View Slide

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

    6 / 20

    View Slide

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

    7 / 20

    View Slide

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

    8 / 20

    View Slide

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

    9 / 20

    View Slide

  10. 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

    View Slide

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

    11 / 20

    View Slide

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

    12 / 20

    View Slide

  13. 最初期
    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

    View Slide

  14. 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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide

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

    17 / 20

    View Slide

  18. 参考(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

    View Slide

  19. 参考(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

    View Slide

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

    20 / 20

    View Slide