3
現在、Pythonで書かれているテキスト処理スクリプトの一部を高速化するためにRustを使用したいと考えていました。ファイル解析時にPythonよりも錆が遅い
二つの言語のパフォーマンスをテストするために、私は非常に単純なタスクにそれらをテストすることを決めた:、STDIN
からファイルに
- 読む行ずつ。
- 行が
>
で始まる場合は、行をheaders.txt
ファイルに保存します。 - それ以外の場合は、
sequences.txt
ファイルに保存してください。このテストのために
、私は次のように見えた10万行とFASTAファイルを使用しています:ここで
$ head uniparc_active-head.fasta
>UPI0000000001 status=active
MGAAASIQTTVNTLSERISSKLEQEANASAQTKCDIEIGNFYIRQNHGCNLTVKNMCSAD
ADAQLDAVLSAATETYSGLTPEQKAYVPAMFTAALNIQTSVNTVVRDFENYVKQTCNSSA
VVDNKLKIQNVIIDECYGAPGSPTNLEFINTGSSKGNCAIKALMQLTTKATTQIAPKQVA
GTGVQFYMIVIGVIILAALFMYYAKRMLFTSTNDKIKLILANKENVHWTTYMDTFFRTSP
MVIATTDMQN
>UPI0000000002 status=active
MMTPENDEEQTSVFSATVYGDKIQGKNKRKRVIGLCIRISMVISLLSMITMSAFLIVRLN
QCMSANEAAITDAAVAVAAASSTHRKVASSTTQYDHKESCNGLYYQGSCYILHSDYQLFS
DAKANCTAESSTLPNKSDVLITWLIDYVEDTWGSDGNPITKTTSDYQDSDVSQEVRKYFC
は私のPythonスクリプトです:
import fileinput
with open('headers.txt', 'w') as hof, \
open('sequences.txt', 'w') as sof:
for line in fileinput.input():
if line[0] == '>':
hof.write(line)
else:
sof.write(line)
と私の錆スクリプト(cargo build --release
でコンパイル):
use std::io;
use std::fs::File;
use std::io::Write;
use std::io::BufRead;
fn main() {
let stdin = io::stdin();
let mut headers = File::create("headers.txt").unwrap();
let mut sequences = File::create("sequences.txt").unwrap();
for line in stdin.lock().lines() {
let line = line.unwrap();
match &line[..1] {
">" => writeln!(headers, "{}", line).unwrap(),
_ => writeln!(sequences, "{}", line).unwrap(),
}
}
}
の実行しているいくつかのベンチマーク:
のPython 2.7
$ time bash -c 'cat uniparc_active-head.fasta | python2 src/main.py'
real 0m11.704s
user 0m6.996s
sys 0m1.100s
のPython 3.5
$ time bash -c 'cat uniparc_active-head.fasta | python3 src/main.py'
real 0m16.788s
user 0m12.508s
sys 0m1.576s
PyPy 5.3.1
$ time bash -c 'cat uniparc_active-head.fasta | pypy src/main.py'
real 0m6.526s
user 0m1.536s
sys 0m0.884s
錆1.14.0
$ cargo build --release
$ time bash -c 'cat uniparc_active-head.fasta | target/release/parse_text'
real 0m17.493s
user 0m2.728s
sys 0m15.408s
錆はPyPyよりも3倍遅く、Python 3よりも遅くなります。
誰もがこれに光を当てることができますか?私は錆のコードで間違いを犯しましたか?もしそうでなければ、私はテキストファイルを処理するためにPython/PyPyに固執すべきでしょうか、あるいは仕事のためにもっと良い言語がありますか?
let mut headers = io::BufWriter::new(File::create("headers.txt").unwrap());
let mut sequences = io::BufWriter::new(File::create("sequences.txt").unwrap());
で
let mut headers = File::create("headers.txt").unwrap();
let mut sequences = File::create("sequences.txt").unwrap();
を交換
@ BurntSushi5によって示唆されるように
奇妙なことに、私は非常に似たような状況に出くわしましたちょうど数日前 - Juliaにテキストパーサを書き直しました。オリジナルのPythonバージョンは3倍高速です。 – TigerhawkT3
あなたの錆プログラムはバッファライタを使用していません。あなたの 'File :: create(...)。unwrap()'呼び出しを 'io :: BufWriter :: new(File :: create(...)unwrap())'に置き換えてみてください。 – BurntSushi5
@ BurntSushi5ええ、ありがとう!私は何か基本的なものが欠けていたと感じました。 – ostrokach