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

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

More than 3 years have 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

gyu-don
来世はパンダになりたい。
https://github.com/gyu-don/
mdrft
量子コンピュータのアプリケーション、ミドルウェア、ハードウェアをフルスタックで開発
https://blueqat.com/
Why not register and get more from Qiita?
  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