Open
Description
Heyo there,
when writing serde_json::to_writer
on BytesMut
vs. writing serde_json::to_vec
I saw a slowdown of roughly 40% depending on input size – while I expected them to perform equally fast.
The following benchmarks
#[bench]
fn bytes_mut_io_write(b: &mut Bencher) {
use std::io::Write;
let mut buffer = BytesMut::with_capacity(128);
let bytes = b"foo bar baz quux lorem ipsum dolor et";
b.bytes = bytes.len() as u64;
b.iter(|| {
(&mut buffer).writer().write(bytes).unwrap();
test::black_box(&buffer);
unsafe {
buffer.set_len(0);
}
})
}
#[bench]
fn vec_io_write(b: &mut Bencher) {
use std::io::Write;
let mut buffer = Vec::with_capacity(128);
let bytes = b"foo bar baz quux lorem ipsum dolor et";
b.bytes = bytes.len() as u64;
b.iter(|| {
buffer.write(bytes).unwrap();
test::black_box(&buffer);
unsafe {
buffer.set_len(0);
}
})
}
yielded
bytes $ cargo +nightly bench --bench bytes_mut vec_io_write
Finished bench [optimized] target(s) in 0.00s
Running unittests (target/release/deps/bytes_mut-d70aabe3863f1aa3)
running 1 test
test vec_io_write ... bench: 2 ns/iter (+/- 0) = 18500 MB/s
test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 19 filtered out; finished in 5.73s
bytes $ cargo +nightly bench --bench bytes_mut bytes_mut_io_write
Finished bench [optimized] target(s) in 0.00s
Running unittests (target/release/deps/bytes_mut-d70aabe3863f1aa3)
running 1 test
test bytes_mut_io_write ... bench: 7 ns/iter (+/- 0) = 5285 MB/s
test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured; 19 filtered out; finished in 0.17s
Some more integrated benchmarks:
pub fn to_bytes<T>(value: &T) -> serde_json::Result<BytesMut>
where
T: ?Sized + Serialize,
{
let mut bytes = BytesMut::with_capacity(128);
serde_json::to_writer((&mut bytes).writer(), value)?;
Ok(bytes)
}
to_bytes(&log)
279.92 ns
pub fn to_bytes<T>(value: &T) -> serde_json::Result<BytesMut>
where
T: ?Sized + Serialize,
{
let bytes = serde_json::to_vec(value)?;
let bytes = BytesMut::from(bytes.as_slice());
Ok(bytes)
}
to_bytes(&log)
226.44 ns
serde_json::to_vec(&log)
195.28 ns
Give that even writing to Vec<u8>
and copying the result over to a new BytesMut
was faster than taking the Writer
, I think this could use some attention.
I'm wondering if this is a conceputal difference in BytesMut
or something that could be improved via #425/#478?
Metadata
Metadata
Assignees
Labels
No labels