The rust input file is very slow compared to C. Is something wrong?

To compare the file I / O performance between C and Rust, I write a β€œtest” to a file 100,000,000 times and read 4 bytes from a file 100,000,000 times.

Compared to C, the rust code spent over 450 times sys time for writing and 140 times for reading.

I suspect there are better ways to achieve fast I / O; How to improve file I / O performance in 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 

Rust code to write:

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

Rust code to read:

 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 code to write:

 #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 code to read:

 #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; } 
+5
source share
1 answer

My Rust program did not use buffered I / O. Thanks to comments by BurntSushi5 and Andrew Henle, the problem is resolved.

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

I changed the code:

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

and

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

Now I / O is buffered.

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

Performance is as fast as C.

 $ time ./rswrite real 0m1.341s user 0m0.213s sys 0m0.200s $ time ./rsread_buf real 0m0.596s user 0m0.540s sys 0m0.050s 
+8
source

Source: https://habr.com/ru/post/1265920/


All Articles