3
我曾希望使用Rust來加速當前用Python編寫的一些文本處理腳本。在解析文件時比解析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
So Rust比PyPy慢3倍,甚至比Python 3慢。
任何人都可以對此有所瞭解嗎?我在Rust代碼中犯了錯誤嗎?如果沒有,我應該堅持Python/PyPy來處理文本文件,還是有另一種語言對工作更好?
奇怪的是,我偶然發現一個類似的情況就在幾天前 - 我重寫了Julia中的文本解析器,原始Python版本速度提高了3倍。 – TigerhawkT3
您的Rust程序未使用緩衝作家。嘗試用'io :: BufWriter :: new(File :: create(...)。unwrap())'替換你的'File :: create(...)。unwrap()'調用。 – BurntSushi5
@ BurntSushi5喲,謝謝!我有一種感覺,我錯過了一些基本的東西。 – ostrokach