最速... gccの助けを借りてそれを行うことができます。これは、指定された場合は指定されたファイル名から、そうでない場合は標準入力からデータを読み取るバージョンです。getchar()
これでも遅すぎる場合は、 and putchar()
(マクロである可能性があり、最適化する必要があります) を独自のバッファリング コードに置き換えることで、高速化できるかどうかを確認できます。馬鹿げたことをしたい場合は、さらに高速にするために 3 つのスレッドを用意する必要があります。そのため、カーネルは次のデータ ブロックを 1 つのコアでコピーし、別のコアが処理を行い、3 つ目のコアが処理された出力をカーネルにコピーします。
#!/bin/bash
set -e
BINNAME=$(mktemp)
gcc -xc -O3 -o $BINNAME - <<"EOF"
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int sep = 0;
/* speed is a requirement, so let's reduce io overhead */
const int bufsize = 1024*1024;
setvbuf(stdin, malloc(bufsize), _IOFBF, bufsize);
setvbuf(stdout, malloc(bufsize), _IOFBF, bufsize);
/* above buffers intentionally not freed, it doesn't really matter here */
int ch;
while((ch = getc(stdin)) >= 0) {
if (isdigit(ch) || isspace(ch)) {
if (!sep) {
if (putc('\n', stdout) == EOF) break;
sep = 1;
}
} else {
sep = 0;
if (putc(ch, stdout) == EOF) break;
}
}
/* flush should happen by on-exit handler, as buffer is not freed,
but this will detect write errors, for program exit code */
fflush(stdout);
return ferror(stdin) || ferror(stdout);
}
EOF
if [ -z "$1" ] ; then
$BINNAME <&0
else
$BINNAME <"$1"
fi
編集: たまたま GNU/Linux stdio.h を見て、いくつかのメモ: putchar
/getchar
はマクロではありませんが、putc
/getc
であるため、代わりにそれらを使用すると、わずかな最適化が行われる可能性があり、おそらく 1 つの関数呼び出しを回避し、これを反映するようにコードを変更しました。また、 のリターン コードのチェックを追加putc
しました。