Skip to content

Instantly share code, notes, and snippets.

@abonander
Created February 7, 2016 04:05
Show Gist options
  • Save abonander/ce5e989c6ac6823acea4 to your computer and use it in GitHub Desktop.
Save abonander/ce5e989c6ac6823acea4 to your computer and use it in GitHub Desktop.
Test of `posix_fadvise()` for Rust
$ # Generate 8 MB of random data
$ head -c 8M < /dev/urandom > data.txt
$ # Flush and clear the cache so we get the data from disk
$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches && cargo script posix_fadvise_test.rs
3
Compiling posix_fadvise_test v0.1.0 (file:///home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286)
Advised result: HashResult { hash: [173, 168, 157, 204, 185, 126, 165, 177, 195, 111, 94, 179, 252, 59, 25, 169], time: Duration { secs: 0, nanos: 10050785 } }
$ # Comment out the call to advise_willneed, save, flush again and re-run
$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches && cargo script posix_fadvise_test.rs
3
Compiling posix_fadvise_test v0.1.0 (file:///home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286)
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:40:1: 53:2 warning: function is never used: `advise_willneed`, #[warn(dead_code)] on by default
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:40 fn advise_willneed(file: &File) {
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:41 let len = file.metadata().unwrap().len();
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:42
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:43 unsafe {
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:44 assert_eq!(
/home/austin/.cargo/script-cache/file-posix_fadvise_test-8d6a7e80a3131286/posix_fadvise_test.rs:45 libc::posix_fadvise(
...
Advised result: HashResult { hash: [173, 168, 157, 204, 185, 126, 165, 177, 195, 111, 94, 179, 252, 59, 25, 169], time: Duration { secs: 0, nanos: 33213398 } }
$ # Significantly slower!
//! ```cargo
//!
//! [dependencies]
//! md5 = "*"
//!
//! [dependencies.libc]
//! path = "/home/austin/Rust/libc/"
//! ```
#![feature(time2)]
extern crate libc;
extern crate md5;
use md5::Digest;
use std::io::prelude::*;
use std::fs::File;
use std::os::unix::io::AsRawFd;
use std::time::{Duration, Instant};
use std::thread;
#[derive(Debug)]
struct HashResult {
hash: Digest,
time: Duration,
}
fn main() {
let mut data_buf = File::open("data.txt").expect("Expected data.txt");
advise_willneed(&data_buf);
// Give the system time to read the file into the cache; in practice we'd be doing other stuff here in userspace.
thread::sleep(Duration::from_millis(1000));
let buf = read_and_hash(&mut data_buf);
println!("Advised result: {:?}", buf);
}
fn advise_willneed(file: &File) {
let len = file.metadata().unwrap().len();
unsafe {
assert_eq!(
libc::posix_fadvise(
file.as_raw_fd(),
0, len as libc::off_t,
libc::POSIX_FADV_WILLNEED
),
0
);
}
}
fn read_and_hash(file: &mut File) -> HashResult {
let start = Instant::now();
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
let read_time = start.elapsed();
let digest = md5::compute(&data);
HashResult {
hash: digest,
time: read_time,
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment