mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-28 00:00:17 +02:00
Optimize BytesMut::reserve: Reuse vec if possible (#529)
* Optimize `BytesMut::reserve`: Reuse vec if possible If the `BytesMut` holds a unqiue reference to `KIND_ARC` while the capacity of the `Vec` is not big enough , reuse the existing `Vec` instead of allocating a new one. Signed-off-by: Jiahao XU <[email protected]>
This commit is contained in:
+28
-12
@@ -644,21 +644,37 @@ impl BytesMut {
|
|||||||
|
|
||||||
self.ptr = vptr(ptr);
|
self.ptr = vptr(ptr);
|
||||||
self.cap = v.capacity();
|
self.cap = v.capacity();
|
||||||
|
} else {
|
||||||
|
// calculate offset
|
||||||
|
let off = v.capacity() - self.cap;
|
||||||
|
|
||||||
return;
|
// new_cap is calculated in terms of `BytesMut`, not the underlying
|
||||||
|
// `Vec`, so it does not take the offset into account.
|
||||||
|
//
|
||||||
|
// Thus we have to manually add it here.
|
||||||
|
new_cap = new_cap.checked_add(off).expect("overflow");
|
||||||
|
|
||||||
|
// The vector capacity is not sufficient. The reserve request is
|
||||||
|
// asking for more than the initial buffer capacity. Allocate more
|
||||||
|
// than requested if `new_cap` is not much bigger than the current
|
||||||
|
// capacity.
|
||||||
|
//
|
||||||
|
// There are some situations, using `reserve_exact` that the
|
||||||
|
// buffer capacity could be below `original_capacity`, so do a
|
||||||
|
// check.
|
||||||
|
let double = v.capacity().checked_shl(1).unwrap_or(new_cap);
|
||||||
|
|
||||||
|
new_cap = cmp::max(double, new_cap);
|
||||||
|
|
||||||
|
// No space - allocate more
|
||||||
|
v.reserve(new_cap - v.len());
|
||||||
|
|
||||||
|
// Update the info
|
||||||
|
self.ptr = vptr(v.as_mut_ptr().add(off));
|
||||||
|
self.cap = v.capacity() - off;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The vector capacity is not sufficient. The reserve request is
|
return;
|
||||||
// asking for more than the initial buffer capacity. Allocate more
|
|
||||||
// than requested if `new_cap` is not much bigger than the current
|
|
||||||
// capacity.
|
|
||||||
//
|
|
||||||
// There are some situations, using `reserve_exact` that the
|
|
||||||
// buffer capacity could be below `original_capacity`, so do a
|
|
||||||
// check.
|
|
||||||
let double = v.capacity().checked_shl(1).unwrap_or(new_cap);
|
|
||||||
|
|
||||||
new_cap = cmp::max(cmp::max(double, new_cap), original_capacity);
|
|
||||||
} else {
|
} else {
|
||||||
new_cap = cmp::max(new_cap, original_capacity);
|
new_cap = cmp::max(new_cap, original_capacity);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -443,7 +443,7 @@ fn reserve_growth() {
|
|||||||
let _ = bytes.split();
|
let _ = bytes.split();
|
||||||
|
|
||||||
bytes.reserve(65);
|
bytes.reserve(65);
|
||||||
assert_eq!(bytes.capacity(), 128);
|
assert_eq!(bytes.capacity(), 117);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user