mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-02 17:15:43 +00:00
perf: reduce packet buffer slicing churn (#2381)
* bench: add packet bytes extraction Criterion benchmark Adds a Criterion benchmark under easytier/benches/ covering ZCPacket::payload_bytes and tunnel_payload_bytes at 1280/4096-byte payload sizes, using iter_batched so ZCPacket construction stays in the setup phase and is excluded from the timed region. - Register the [[bench]] entry in easytier/Cargo.toml. - Document the bench and PACKET_BYTES_* env vars in benches/README.md. * perf: reduce packet buffer slicing churn Replace BytesMut::split_off with Buf::advance in ZCPacket bytes extraction paths (payload_bytes, tunnel_payload_bytes, convert_type, drop_foreign_header) and in TunZCPacketToBytes, and simplify the copy_from_slice in new_from_payload. When the buffer is in its unique (VEC) representation, split_off promotes it to the shared (ARC) representation, allocating a Shared control block and bumping the refcount on every call, and pins the buffer in shared mode. advance only mutates the in-place ptr/len/cap fields, avoiding that allocation/refcount churn on the TX hot path. The byte data itself is not copied by either path.
This commit is contained in:
@@ -24,7 +24,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use byteorder::WriteBytesExt as _;
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use bytes::{Buf, BufMut, BytesMut};
|
||||
use cidr::{Ipv4Inet, Ipv6Inet};
|
||||
use futures::{SinkExt, Stream, StreamExt, lock::BiLock, ready};
|
||||
use pin_project_lite::pin_project;
|
||||
@@ -180,12 +180,13 @@ impl ZCPacketToBytes for TunZCPacketToBytes {
|
||||
assert!(payload_offset >= 4);
|
||||
|
||||
let ret = if self.has_packet_info {
|
||||
let mut inner = inner.split_off(payload_offset - 4);
|
||||
inner.advance(payload_offset - 4);
|
||||
let proto = infer_proto(&inner[4..]);
|
||||
self.fill_packet_info(&mut inner[0..4], proto)?;
|
||||
inner
|
||||
} else {
|
||||
inner.split_off(payload_offset)
|
||||
inner.advance(payload_offset);
|
||||
inner
|
||||
};
|
||||
|
||||
tracing::debug!(?ret, ?payload_offset, "convert zc packet to tun packet");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use bytes::Buf;
|
||||
use bytes::Bytes;
|
||||
use bytes::BytesMut;
|
||||
use zerocopy::AsBytes;
|
||||
@@ -486,7 +487,7 @@ impl ZCPacket {
|
||||
let total_len = payload_off + payload.len();
|
||||
ret.inner.reserve(total_len);
|
||||
unsafe { ret.inner.set_len(total_len) };
|
||||
ret.mut_payload()[..payload.len()].copy_from_slice(payload);
|
||||
ret.mut_payload().copy_from_slice(payload);
|
||||
ret
|
||||
}
|
||||
|
||||
@@ -587,7 +588,8 @@ impl ZCPacket {
|
||||
}
|
||||
|
||||
pub fn payload_bytes(mut self) -> BytesMut {
|
||||
self.inner.split_off(self.payload_offset())
|
||||
self.inner.advance(self.payload_offset());
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn peer_manager_header(&self) -> Option<&PeerManagerHeader> {
|
||||
@@ -652,11 +654,12 @@ impl ZCPacket {
|
||||
}
|
||||
|
||||
pub fn tunnel_payload_bytes(mut self) -> BytesMut {
|
||||
self.inner.split_off(
|
||||
self.inner.advance(
|
||||
self.packet_type
|
||||
.get_packet_offsets()
|
||||
.peer_manager_header_offset,
|
||||
)
|
||||
);
|
||||
self.inner
|
||||
}
|
||||
|
||||
pub fn convert_type(mut self, target_packet_type: ZCPacketType) -> Self {
|
||||
@@ -702,7 +705,8 @@ impl ZCPacket {
|
||||
return Self::new_from_buf(buf, target_packet_type);
|
||||
}
|
||||
|
||||
Self::new_from_buf(self.inner.split_off(new_offset), target_packet_type)
|
||||
self.inner.advance(new_offset);
|
||||
Self::new_from_buf(self.inner, target_packet_type)
|
||||
}
|
||||
|
||||
pub fn into_bytes(self) -> Bytes {
|
||||
@@ -748,8 +752,10 @@ impl ZCPacket {
|
||||
let foreign_hdr_len = hdr.get_header_len();
|
||||
|
||||
Self::new_from_buf(
|
||||
self.inner
|
||||
.split_off(foreign_hdr_len + self.payload_offset()),
|
||||
{
|
||||
self.inner.advance(foreign_hdr_len + self.payload_offset());
|
||||
self.inner
|
||||
},
|
||||
ZCPacketType::DummyTunnel,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user