私は65536個のファイルに基づくフラットデータベースを持っています。各ファイルには、2つの16進文字で始まる1行の単語が含まれています。
それらは次のとおりです。
afword
46word2
Feword3
...
私はこれについて毎日何万もの要求をしているので、2つの16進文字で始まる行を見つけるより良い方法を探しています。ファイルはgzipの前にソートされます。
現在私はこうする:
LC=ALL zgrep --text '^af' file
Perl、Bash、またはコマンドラインでこれを行う他のより速い方法はありますか?
答え1
zgrep
(添付gzip
)は最終的に同様のことをするシェルスクリプトですzcat | grep
。zutils
C ++で書かれており、より多くの圧縮形式をサポートしていることを除いて、同じことを行います。それでもパイプを介して接続された別のプロセスを呼び出しgzip
ます。grep
このような簡単な検索では、grep
作業はzcat
それよりはるかに簡単なので、データを整理するのと同じアプローチを維持する場合は、圧縮の側面を改善することに集中することをお勧めします。
hereを使用して生成されたファイルを扱うときにxxd -p -c35 < /dev/urandom | head -n 760000 | sort
gzipで圧縮されていることがわかりました。pigz -dc
代わりにzcat
(別名gzip -dc
)を使用すると、速度が2倍に増加しました。
圧縮するとlz4 --best
30%大きいファイルが得られましたが、解凍するのに100倍少ない時間がかかりました。
$ zstat +size a*(m-1)| sort -k2n | column -t
a.xz 26954744
a.lrz 26971363
a.bz2 27412562
a.gz 30353089
a.gz3 30727911
a.lzop 38000050
a.lz4 40261510
a 53960000
$ time lz4cat a.lz4 > /dev/null
lz4cat a.lz4 > /dev/null 0.06s user 0.01s system 98% cpu 0.064 total
$ time pigz -dc a.gz > /dev/null
pigz -dc a.gz > /dev/null 0.36s user 0.02s system 126% cpu 0.298 total
$ time gzip -dc a.gz > /dev/null
gzip -dc a.gz > /dev/null 0.47s user 0.00s system 99% cpu 0.476 total
$ time lz4cat a.lz4 | LC_ALL=C grep '^af' > /dev/null
lz4cat a.lz4 0.07s user 0.02s system 60% cpu 0.142 total
LC_ALL=C grep '^af' > /dev/null 0.07s user 0.00s system 53% cpu 0.141 total
$ time pigz -dc a.gz | LC_ALL=C grep '^af' > /dev/null
pigz -dc a.gz 0.36s user 0.04s system 130% cpu 0.303 total
LC_ALL=C grep '^af' > /dev/null 0.06s user 0.01s system 23% cpu 0.302 total
$ time gzip -dc a.gz | LC_ALL=C grep '^af' > /dev/null
gzip -dc a.gz 0.51s user 0.00s system 99% cpu 0.513 total
LC_ALL=C grep '^af' > /dev/null 0.08s user 0.01s system 16% cpu 0.512 total
lzop --best
lz4
私のサンプルでは近い秒で、少しよく圧縮されました。
$ time lzop -dc a.lzop | LC_ALL=C grep '^af' > /dev/null
lzop -dc a.lzop 0.24s user 0.01s system 85% cpu 0.293 total
LC_ALL=C grep '^af' > /dev/null 0.07s user 0.01s system 27% cpu 0.292 total