2017-03-26 6 views
5

CとRustの間のファイルI/Oパフォーマンスを比較するために、 "test"をファイルに100,000,000回書き、ファイルから4バイトを100,000,000回読みます。Rustファイルの入出力はCと比較して非常に遅いですか?

Cと比較すると、書き込みコードはsys時間の450倍以上、読み取りには140回以上費やされました。

高速I/Oを実現するためのより良い方法があると思われます。 RustのファイルI/Oのパフォーマンスをどのように改善するのですか?

$ rustc --version 
rustc 1.16.0 
$ rustc rswrite.rs -C opt-level=3 # Rust for writing 
$ time ./rswrite 
real 1m8.411s 
user 0m3.817s 
sys  1m4.533s 
$ rustc rsread.rs -C opt-level=3 # Rust for reading 
$ time ./rsread 
real 0m18.077s 
user 0m2.130s 
sys  0m15.910s 
$ gcc -O3 cwrite.c -ocwrite # C for writing 
$ time ./cwrite 
real 0m1.564s 
user 0m1.397s 
sys  0m0.143s 
$ gcc -O3 cread.c -ocread # C for reading 
$ time ./cread 
real 0m1.353s 
user 0m1.240s 
sys  0m0.113s 

書き込みのため錆コード:

use std::fs; 
use std::io::Write; 
fn main() { 
    let b = b"test"; 
    let mut f = fs::File::create("rs.dump").unwrap(); 
    for _ in 0 .. 100_000_000 { 
     f.write(b).unwrap(); 
    } 
} 

読書のための錆コード:執筆のための

use std::{fs, mem}; 
use std::io::Read; 
fn main() { 
    let mut f = fs::File::open("rs.dump").unwrap(); 
    let mut b: [u8; 4] = unsafe { mem::uninitialized() }; 
    for _ in 0 .. 100_000_000 { 
     f.read_exact(&mut b).unwrap(); 
    } 
} 

Cコード:読書のための

#include <stdio.h> 
#define N 100000000 
int main() 
{ 
    const char *teststr = "test"; 
    FILE *fp = fopen("c.dump", "wb"); 
    unsigned long long i; 
    for (i=0; i<N; i++) fwrite(teststr, 4, 1, fp); 
    fclose(fp); 
    return 0; 
} 

Cコード:

#include <stdio.h> 
#define N 100000000 

int main() { 
    FILE *fp = fopen("c.dump", "rb"); 
    long long i; 
    char buf[4]; 
    for (i=0; i<N; i++) fread(buf, 4, 1, fp); 
    fclose(fp); 
    return 0; 
} 
+7

あなたのCプログラムは、バッファIOを使用しています。あなたの錆のプログラムはありません。 – BurntSushi5

+1

Rustの下の 'sys'時間は恐ろしいものです。あなたがLinuxで走っているなら、 'strace'の下でプロセスを実行して、異なるプロセスが実際に行っているシステムコールを見てください。 –

+0

@AndrewHenle:良いアドバイス。 I/OがデフォルトでRustにバッファリングされていないことが明らかになります。もちろん、これはシステムコールの大部分を意味します。 –

答えて

8

私の錆プログラムは、バッファされたIOを使用していませんでした。 BurntSushi5とAndrew Henleのコメントのおかげで、問題は解決されました。 Iコード変性

$ strace ./rswrite 
write(3, "test", 4)      = 4 
write(3, "test", 4)      = 4 
... 
$ strace ./rswrite 
read(3, "test", 4)      = 4 
read(3, "test", 4)      = 4 
... 

:今

use std::fs; 
use std::io::{BufWriter, Write}; 
fn main() { 
    let b = b"test"; 
    /**** Use std::io::BufWriter ****/ 
    let mut f = BufWriter::new(fs::File::create("rs.dump").unwrap()); 
    for _ in 0 .. 100_000_000 { 
     f.write(b).unwrap(); 
    } 
} 

use std::{fs, mem}; 
use std::io::{BufReader, Read}; 
fn main() { 
    /**** Use std::io::BufReader ****/ 
    let mut f = BufReader::new(fs::File::open("rs.dump").unwrap()); 
    let mut b: [u8; 4] = unsafe { mem::uninitialized() }; 
    for _ in 0 .. 100_000_000 { 
     f.read_exact(&mut b).unwrap(); 
    } 
} 

を、I/Oがバッファリングされます。

write(3, "testtesttesttesttesttesttesttest"..., 8192) = 8192 
write(3, "testtesttesttesttesttesttesttest"..., 8192) = 8192 
... 

パフォーマンスが早くC.

として
$ time ./rswrite 
real 0m1.341s 
user 0m0.213s 
sys  0m0.200s 
$ time ./rsread_buf 
real 0m0.596s 
user 0m0.540s 
sys  0m0.050s 
関連する問題