はじまり
yesコマンドに関する記事をたまたま読んだのでちょっとやってみた。
Unixコマンド”yes”についてのちょっとした話 | コンピュータサイエンス | POSTD
私は標準入力のロックはやっていません。
print系の関数だと可変引数のサポートが邪魔しそうなので基本的にwriteを使っています。
とりあえず
私のArchLinuxにビルトインのyesコマンド(GNU coreutils 8.29)
$ yes | pv -r > /dev/null
8.63GiB/sくらい
C
gcc(7.3.0)で特に最適化とか入れてません
##バッファなし
#include <unistd.h>
#define LEN 2
int main() {
char yes[LEN] = "y\n";
while (1) {
write(1, yes, LEN);
}
}
4.44MiB/sくらい
思ってたより遅い
##バッファ有り(8KB)
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 8192
#define LEN 2
int main() {
char *buf = malloc(BUFSIZE);
int i;
char yes[LEN] = "y\n";
for (i = 0; i < BUFSIZE; i += LEN) {
memcpy(buf + i, yes, sizeof(char) * LEN);
}
while (1) {
write(1, buf, BUFSIZE);
}
}
8.85GiB/sくらい
あれ、これ変なメモリに書き込んでるような
ビルトインのyesよりちょっと速いのはバッファサイズの関係かなと
Python
3.6.4
バッファなし
import sys
while True:
sys.stdout.write('y\n')
14.2MiB/sくらい
Cのバッファなしより速い
バッファ有り(8KB)
import sys
BUF_SIZE = 8192
yes = ''
while len(yes) <= BUF_SIZE:
yes += 'y\n'
while True:
sys.stdout.write(yes)
4.07GiB/sくらい
インタプリタの割に結構早い
本命のシェルスクリプトでやってみた
バッファなし
$ while true; do echo y; done | pv -r > /dev/null
890KiB/sくらい
バッファ有り(8KBのファイル)
$ for i in `seq 4096`; do echo y; done > yes8kb.txt; while true; do cat yes8kb.txt; done | pv -r > /dev/null
2.93MiB/sくらい
無理矢理(1GBのファイルを作ってやってみた)
$ for i in `seq 524288`; do echo y; done > yes1mb.txt; for i in `seq 1024`; do cat yes1mb.txt; done > yes1g.txt; while true; do cat yes1g.txt; done | pv -r > /dev/null
4.93GiB/sくらい
感想
シェルスクリプトcatコマンドが健闘
もっといい書き方がありそう