2017-03-26 17 views
5

Để so sánh hiệu suất I/O của tệp giữa C và Rust, tôi viết "test" thành một tệp 100,000,000 lần và đọc 4 byte từ một tệp 100,000,000 lần.I/O tệp Rust rất chậm so với C. Có gì sai không?

So với C, mã Rust đã dành hơn 450 lần thời gian sys để viết và 140 lần để đọc.

Tôi nghi ngờ có những cách tốt hơn để đạt được I/O nhanh; làm cách nào để cải thiện hiệu suất của tệp I/O trong Rust?

$ 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 

đang Rust để viết:

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(); 
    } 
} 

đang Rust cho Reading:

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 mã cho Viết:

#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; 
} 

mã C cho Reading:

#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

chương trình C bạn đang sử dụng đệm IO. Chương trình Rust của bạn thì không. – BurntSushi5

+1

Thời gian 'sys' trong Rust là khủng khiếp. Nếu bạn đang chạy trên Linux, hãy chạy các quy trình dưới 'strace' và xem hệ thống nào gọi các quá trình khác nhau đang thực sự tạo ra. –

+0

@AndrewHenle: Lời khuyên hay; nó sẽ tiết lộ rằng I/O không được đệm theo mặc định trong Rust, tất nhiên có nghĩa là có rất nhiều cuộc gọi hệ thống. –

Trả lời

8

Chương trình Rust của tôi không sử dụng bộ đệm IO. Nhờ ý kiến ​​của BurntSushi5 và Andrew Henle, vấn đề được giải quyết.

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

tôi sửa đổi mã:

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(); 
    } 
} 

Bây giờ, I/O được đệm.

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

Việc thực hiện là nhanh như C.

$ time ./rswrite 
real 0m1.341s 
user 0m0.213s 
sys  0m0.200s 
$ time ./rsread_buf 
real 0m0.596s 
user 0m0.540s 
sys  0m0.050s 
Các vấn đề liên quan