mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-26 00:00:20 +02:00
Add inline attributes to Vec's MutBuf methods (#80)
I found this significantly improved a [benchmark](https://gist.github.com/danburkert/34a7d6680d97bc86dca7f396eb8d0abf) which calls `bytes_mut`, writes 1 byte, and advances the pointer with `advance_mut` in a pretty tight loop. In particular, it seems to be the inline annotation on `bytes_mut` which had the most effect. I also took the opportunity to simplify the bounds checking in advance_mut. before: ``` test encode_varint_small ... bench: 540 ns/iter (+/- 85) = 1481 MB/s ``` after: ``` test encode_varint_small ... bench: 422 ns/iter (+/- 24) = 1895 MB/s ``` As you can see, the variance is also significantly improved. Interestingly, I tried to change the last statement in `bytes_mut` from ``` &mut slice::from_raw_parts_mut(ptr, cap)[len..] ``` to ``` slice::from_raw_parts_mut(ptr.offset(len as isize), cap - len) ``` but, this caused a very measurable perf regression (almost completely negating the gains from marking bytes_mut inline).
This commit is contained in:
+10
-8
@@ -699,23 +699,25 @@ impl<T: AsMut<[u8]> + AsRef<[u8]>> BufMut for io::Cursor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BufMut for Vec<u8> {
|
impl BufMut for Vec<u8> {
|
||||||
|
#[inline]
|
||||||
fn remaining_mut(&self) -> usize {
|
fn remaining_mut(&self) -> usize {
|
||||||
usize::MAX - self.len()
|
usize::MAX - self.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn advance_mut(&mut self, cnt: usize) {
|
unsafe fn advance_mut(&mut self, cnt: usize) {
|
||||||
let cap = self.capacity();
|
let len = self.len();
|
||||||
let len = self.len().checked_add(cnt)
|
let remaining = self.capacity() - len;
|
||||||
.expect("overflow");
|
if cnt > remaining {
|
||||||
|
// Reserve additional capacity, and ensure that the total length
|
||||||
if len > cap {
|
// will not overflow usize.
|
||||||
// Reserve additional
|
self.reserve(cnt - remaining);
|
||||||
self.reserve(cap - len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_len(len);
|
self.set_len(len + cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
unsafe fn bytes_mut(&mut self) -> &mut [u8] {
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user