2016-12-30 11 views
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によって示唆されるように
+1

奇妙なことに、私は非常に似たような状況に出くわしましたちょうど数日前 - Juliaにテキストパーサを書き直しました。オリジナルのPythonバージョンは3倍高速です。 – TigerhawkT3

+5

あなたの錆プログラムはバッファライタを使用していません。あなたの 'File :: create(...)。unwrap()'呼び出しを 'io :: BufWriter :: new(File :: create(...)unwrap())'に置き換えてみてください。 – BurntSushi5

+0

@ BurntSushi5ええ、ありがとう!私は何か基本的なものが欠けていたと感じました。 – ostrokach

答えて

6

は、私が期待したものにスピードを育てた:

$ time bash -c 'cat uniparc_active-head.fasta | target/release/parse_text' 
real 0m5.645s 
user 0m1.396s 
sys  0m0.804s 
関連する問題