Skip to content

Commit f3c7f67

Browse files
Optimize FileSerializationSink by using parking_lot::Mutex and avoiding heap allocations in write_atomic.
1 parent 5d01e61 commit f3c7f67

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

measureme/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ travis-ci = { repository = "rust-lang/measureme" }
1515
[dependencies]
1616
byteorder = "1.2.7"
1717
rustc-hash = "1.0.1"
18+
parking_lot = "0.9"
1819

1920
[target.'cfg(not(target_arch="wasm32"))'.dependencies]
2021
memmap = "0.6.0"
Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
use crate::serialization::{Addr, SerializationSink};
22
use std::error::Error;
33
use std::fs;
4-
use std::io::{BufWriter, Write};
4+
use std::io::{Write};
55
use std::path::Path;
6-
use std::sync::Mutex;
6+
use parking_lot::Mutex;
77

88
pub struct FileSerializationSink {
9-
data: Mutex<(BufWriter<fs::File>, u32)>,
9+
data: Mutex<Inner>,
10+
}
11+
12+
struct Inner {
13+
file: fs::File,
14+
buffer: Vec<u8>,
15+
buf_pos: usize,
16+
addr: u32,
1017
}
1118

1219
impl SerializationSink for FileSerializationSink {
@@ -16,7 +23,12 @@ impl SerializationSink for FileSerializationSink {
1623
let file = fs::File::create(path)?;
1724

1825
Ok(FileSerializationSink {
19-
data: Mutex::new((BufWriter::new(file), 0)),
26+
data: Mutex::new(Inner {
27+
file,
28+
buffer: vec![0; 1024*512],
29+
buf_pos: 0,
30+
addr: 0
31+
}),
2032
})
2133
}
2234

@@ -25,17 +37,45 @@ impl SerializationSink for FileSerializationSink {
2537
where
2638
W: FnOnce(&mut [u8]),
2739
{
28-
let mut buffer = vec![0; num_bytes];
29-
write(buffer.as_mut_slice());
40+
let mut data = self.data.lock();
41+
let Inner {
42+
ref mut file,
43+
ref mut buffer,
44+
ref mut buf_pos,
45+
ref mut addr
46+
} = *data;
3047

31-
let mut data = self.data.lock().expect("couldn't acquire lock");
32-
let curr_addr = data.1;
33-
let file = &mut data.0;
48+
assert!(num_bytes <= buffer.len());
49+
let mut buf_start = *buf_pos;
50+
let mut buf_end = buf_start + num_bytes;
3451

35-
file.write_all(&buffer).expect("failed to write buffer");
52+
if buf_end > buffer.len() {
53+
file.write_all(&buffer[..buf_start]).expect("failed to write buffer");
54+
buf_start = 0;
55+
buf_end = num_bytes;
56+
}
3657

37-
data.1 += num_bytes as u32;
58+
write(&mut buffer[buf_start .. buf_end]);
59+
*buf_pos = buf_end;
3860

61+
let curr_addr = *addr;
62+
*addr += num_bytes as u32;
3963
Addr(curr_addr)
4064
}
4165
}
66+
67+
impl Drop for FileSerializationSink {
68+
fn drop(&mut self) {
69+
let mut data = self.data.lock();
70+
let Inner {
71+
ref mut file,
72+
ref mut buffer,
73+
ref mut buf_pos,
74+
addr: _,
75+
} = *data;
76+
77+
if *buf_pos > 0 {
78+
file.write_all(&buffer[..*buf_pos]).expect("failed to write buffer");
79+
}
80+
}
81+
}

measureme/src/serialization.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::error::Error;
22
use std::path::Path;
3-
use std::sync::Mutex;
3+
use parking_lot::Mutex;
44

55
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
66
pub struct Addr(pub u32);
@@ -34,7 +34,7 @@ impl ByteVecSink {
3434
}
3535

3636
pub fn into_bytes(self) -> Vec<u8> {
37-
self.data.into_inner().unwrap()
37+
self.data.into_inner()
3838
}
3939
}
4040

@@ -47,7 +47,7 @@ impl SerializationSink for ByteVecSink {
4747
where
4848
W: FnOnce(&mut [u8]),
4949
{
50-
let mut data = self.data.lock().unwrap();
50+
let mut data = self.data.lock();
5151

5252
let start = data.len();
5353

0 commit comments

Comments
 (0)