Help us understand the problem. What is going on with this article?

RustのファイルI/OにはBufReader, BufWriterを使いましょう、という話

More than 1 year has passed since last update.

Rustが得意なフレンズになりたくて、人の書いたCのコードを、Rustに写経しています。
で、作っていたら、ファイルI/Oが、悲惨なレベルで遅いことに気づきました。

とても遅い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();
    }
}
とても遅い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();
    }
}

何が悪いか、分かりますか? まぁ、タイトル読めば分かりますよね。
実は、Rustのファイルのwrite, read_exactは、バッファリングされていません。
なので、このコードは、4バイトずつ読み書きするために10万回のシステムコールを呼び出します。
じゃあCのfread, fwriteは? そっちはバッファリングされているらしいのです。

https://linuxjm.osdn.jp/html/LDP_man-pages/man3/stdio.3.html

標準入出力ライブラリは、簡単かつ効果のよい、 バッファーリングされたストリーム入出力インターフェースを提供する。

ふぇぇ、manページの最初に書いてあるのに、知らなかったし、考えたこともなかった。

そういうわけなので。ファイルI/Oでは std::io::{BufReader, BufWriter} を使うとCと互角の速度になりました。

ふつうに速いwrite
use std::fs;
use std::io::{BufWriter, Write};
fn main() {
    let b = b"test";
    let mut f = BufWriter::new(fs::File::create("rs.dump").unwrap());
    for _ in 0 .. 100_000_000 {
        f.write(b).unwrap();
    }
}
ふつうに速いread
use std::{fs, mem};
use std::io::{BufReader, Read};
fn main() {
    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();
    }
}

Special Thanks

本気で原因分からなかったので、StackOverflowで質問し、教えていただきました。
http://stackoverflow.com/questions/43028653/rust-file-i-o-is-very-slow-compared-with-c-is-something-wrong/43029048

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away