ksh93はなぜそんなに速いのですか?

ksh93はなぜそんなに速いのですか?

したがって、通常、私はテキスト処理(特に大容量ファイルの場合)を見つける傾向がsedあり、通常はシェル自体でこれらの操作を実行しないでください。

しかし、私はこれが変わることができると思います。私はあちこちを見てman kshよりこれを見つけました。

<#pattern     Seeks forward to the beginning of the
              next line containing pattern.

<##pattern    The same as <# except that  the  por‐
              tion  of  the file that is skipped is
              copied to standard output.

実際の実用性に懐疑的で、一度試してみることにしました。私はそうしました:

seq -s'foo bar
' 1000000 >file

...次のような100万行のデータについて:

1foo bar
...
999999foo bar
1000000

...そして、sed以下と比較してみてください。

p='^[^0-8]99999.*bar'
for c in "sed '/$p/q'" "ksh -c ':<##@(~(E)$p)'"    
do </tmp/file eval "time ( $c )"
done | wc -l

したがって、両方のコマンドを達成する必要があります。999999プワこれを行うには、パターンマッチング実装で少なくとも各行の開始と終了を評価する必要があります。また、負のパターンに対して最初の文字を検証する必要があります。簡単なことですが...結果は私が期待していたものとは異なります。

( sed '/^[^0-8]99999.*bar/q' ) \
    0.40s user 0.01s system 99% cpu 0.419 total
( ksh -c ':<##@(~(E)^[^0-8]99999.*bar)' ) \
    0.02s user 0.01s system 91% cpu 0.033 total
1999997

kshここでは ERE とsedBRE が使用されます。以前はシェルモードで同じことをしましたが、ksh結果は変わりませんでした。

kshそれにもかかわらず、これは10倍を超える非常に重要な違いですsed。以前、David Kornが自分のio libを作成し、それを実装したことを読んだことがありますksh。関連がありますか? - しかし、私はそれについてほとんど何も知りません。シェルはなぜそんなにうまく機能しますか?

私にとってもっと驚くべきことは、kshユーザーが要求した場所にオフセットを残すことです。得るために(ほぼ)また(牛のような栄養の一種) sedあなたは使用する必要があります-u-非常に遅い

以下はgrepv。kshテストです。

1000000         #grep + head
( grep -qm1 '^[^0-8]99999.*bar'; head -n1; ) \
    0.02s user 0.00s system 90% cpu 0.026 total
999999foo bar   #ksh + head
( ksh -c ':<#@(~(E)^[^0-8]99999.*bar)'; head -n1; )  \
    0.02s user 0.00s system 73% cpu 0.023 total

kshここでは、ビットはgrep、必ずしもそうではありませんが、ほぼ密接に接続されています。しかし、まだ素晴らしいです。そして kshheadプレビューを開始するための入力を提供今後一致します。

事実というにはとても良いようだと思いました。これらのコマンドは、後で何が違うのですか?

ああ、そしてここにはサブシェルもないようです。

ksh -c 'printf %.5s "${<file;}"'

ベストアンサー1

kshは以下を使用するだけでなく、SFIOただし、独自のカスタムメモリアロケータを使用します。

それでも私の考えでは、sfioがこの場合に違いを生むということです。私はstraceで例を実行してみましたが、kshが約200回(65KBブロック)の読み取り/書き込みを呼び出し、sedが約3400回(4KBブロック)の読み取り/書き込みを呼び出すことがわかります。 sed -uを使用すると、私のラップトップはほとんど溶け、読み込みはバイト単位で、書き込みは行単位で行われます。 Kshは単にlseekを使用します。 Grepは約400個の読み取り(32KBブロック)を使用します。

おすすめ記事