Skip to content

Commit

Permalink
experiment: Improve serialize performance (#297)
Browse files Browse the repository at this point in the history
* pre-alloc buffer for seq

* fix some elidible lifetimes

* suppress one clippy warning

* add more bench cases (#298)

* pre-alloc buffer for seq

* fix some elidible lifetimes

* suppress one clippy warning

* fix elidible lifetime

* cargo fmt

* fix elidible lifetime

* remove random lengh elements

* pre-alloc for MapSerializer

* cargo fmt

* bump version and updated changelog
  • Loading branch information
minghuaw authored Dec 23, 2024
1 parent 32528fe commit 269127d
Show file tree
Hide file tree
Showing 18 changed files with 221 additions and 123 deletions.
2 changes: 1 addition & 1 deletion fe2o3-amqp-cbs/src/put_token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl<'a> PutTokenRequest<'a> {
}
}

impl<'a> Request for PutTokenRequest<'a> {
impl Request for PutTokenRequest<'_> {
const OPERATION: &'static str = PUT_TOKEN;

type Response = PutTokenResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/entity/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl<'a> CreateRequest<'a> {
}
}

impl<'a> Request for CreateRequest<'a> {
impl Request for CreateRequest<'_> {
const OPERATION: &'static str = CREATE;

type Response = CreateResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/entity/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl<'a> DeleteRequest<'a> {
}
}

impl<'a> Request for DeleteRequest<'a> {
impl Request for DeleteRequest<'_> {
const OPERATION: &'static str = DELETE;

type Response = DeleteResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/entity/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl<'a> ReadRequest<'a> {
}
}

impl<'a> Request for ReadRequest<'a> {
impl Request for ReadRequest<'_> {
const OPERATION: &'static str = READ;

type Response = ReadResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/entity/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ impl<'a> UpdateRequest<'a> {
}
}

impl<'a> Request for UpdateRequest<'a> {
impl Request for UpdateRequest<'_> {
const OPERATION: &'static str = UPDATE;

type Response = UpdateResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<'a> GetAnnotationsRequest<'a> {
}
}

impl<'a> Request for GetAnnotationsRequest<'a> {
impl Request for GetAnnotationsRequest<'_> {
const OPERATION: &'static str = GET_ANNOTATIONS;

type Response = GetAnnotationsResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<'a> GetAttributesRequest<'a> {
}
}

impl<'a> Request for GetAttributesRequest<'a> {
impl Request for GetAttributesRequest<'_> {
const OPERATION: &'static str = GET_ATTRIBUTES;

type Response = GetAttributesResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'a> GetMgmtNodesRequest<'a> {
}
}

impl<'a> Request for GetMgmtNodesRequest<'a> {
impl Request for GetMgmtNodesRequest<'_> {
const OPERATION: &'static str = GET_MGMT_NODES;

type Response = GetMgmtNodesResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl<'a> GetOperationsRequest<'a> {
}
}

impl<'a> Request for GetOperationsRequest<'a> {
impl Request for GetOperationsRequest<'_> {
const OPERATION: &'static str = GET_OPERATIONS;

type Response = GetOperationsResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/node/get_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<'a> GetTypesRequest<'a> {
}
}

impl<'a> Request for GetTypesRequest<'a> {
impl Request for GetTypesRequest<'_> {
const OPERATION: &'static str = GET_TYPES;

type Response = GetTypesResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/node/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<'a> QueryRequest<'a> {
}
}

impl<'a> Request for QueryRequest<'a> {
impl Request for QueryRequest<'_> {
const OPERATION: &'static str = QUERY;

type Response = QueryResponse;
Expand Down
2 changes: 1 addition & 1 deletion fe2o3-amqp-management/src/operations/node/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl<'a> RegisterRequest<'a> {
}
}

impl<'a> Request for RegisterRequest<'a> {
impl Request for RegisterRequest<'_> {
const OPERATION: &'static str = REGISTER;

type Response = RegisterResponse;
Expand Down
9 changes: 5 additions & 4 deletions fe2o3-amqp/src/connection/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl<'a, Tls> From<Builder<'a, mode::ConnectorWithId, Tls>> for Open {
}
}

impl<'a, Mode: std::fmt::Debug> std::fmt::Debug for Builder<'a, Mode, ()> {
impl<Mode: std::fmt::Debug> std::fmt::Debug for Builder<'_, Mode, ()> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Builder")
.field("container_id", &self.container_id)
Expand Down Expand Up @@ -254,13 +254,13 @@ cfg_not_wasm32! {
}
}

impl<'a, Mode> Default for Builder<'a, Mode, ()> {
impl<Mode> Default for Builder<'_, Mode, ()> {
fn default() -> Self {
Self::new()
}
}

impl<'a, Mode> Builder<'a, Mode, ()> {
impl<Mode> Builder<'_, Mode, ()> {
/// Creates a new builder for [`crate::Connection`]
pub fn new() -> Self {
Self {
Expand Down Expand Up @@ -323,6 +323,7 @@ impl<'a, Tls> Builder<'a, mode::ConnectorNoId, Tls> {
}
}

#[allow(clippy::needless_lifetimes)]
impl<'a, Mode, Tls> Builder<'a, Mode, Tls> {
/// Alias for [`rustls_connector`](#method.rustls_connector) if only `"rustls"` is enabled
#[cfg_attr(docsrs, doc(cfg(all(feature = "rustls", not(feature = "native-tls")))))]
Expand Down Expand Up @@ -753,7 +754,7 @@ impl<'a, Tls> Builder<'a, mode::ConnectorWithId, Tls> {
/* Without TLS */
/* -------------------------------------------------------------------------- */

impl<'a> Builder<'a, mode::ConnectorWithId, ()> {
impl Builder<'_, mode::ConnectorWithId, ()> {
#[cfg(all(feature = "rustls", not(feature = "native-tls")))]
async fn connect_tls_with_rustls_default<Io, F>(
self,
Expand Down
6 changes: 3 additions & 3 deletions fe2o3-amqp/src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl AsByteIterator for Payload {
}
}

impl<'a> AsByteIterator for &'a Payload {
impl AsByteIterator for &Payload {
type IterImpl<'i>
= std::slice::Iter<'i, u8>
where
Expand Down Expand Up @@ -271,13 +271,13 @@ impl<'a> Iterator for ByteReaderIter<'a> {
}
}

impl<'a> ExactSizeIterator for ByteReaderIter<'a> {
impl ExactSizeIterator for ByteReaderIter<'_> {
fn len(&self) -> usize {
self.inner.iter().map(|iter| iter.len()).sum()
}
}

impl<'a> DoubleEndedIterator for ByteReaderIter<'a> {
impl DoubleEndedIterator for ByteReaderIter<'_> {
fn next_back(&mut self) -> Option<Self::Item> {
self.inner
.iter_mut()
Expand Down
2 changes: 1 addition & 1 deletion serde_amqp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "serde_amqp"
version = "0.13.1"
version = "0.13.2"
edition = "2021"
description = "A serde implementation of AMQP1.0 protocol."
license = "MIT/Apache-2.0"
Expand Down
6 changes: 6 additions & 0 deletions serde_amqp/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 0.13.2

1. Improve serializer performance in serializing list and map types by
pre-allocating the buffer based on the suggested length and the serialized
size of the first element/entry.

## 0.13.1

1. Added `to_lazy_value`
Expand Down
84 changes: 0 additions & 84 deletions serde_amqp/benches/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,42 +283,6 @@ fn criterion_benchmark(c: &mut Criterion) {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// 10 Random strings of size between 16B and 1kB
let value = (0..10)
.map(|_| {
let size = rand::thread_rng().gen_range(16..1024);
Alphanumeric.sample_string(&mut rand::thread_rng(), size)
})
.map(String::from)
.collect::<Vec<_>>();
c.bench_function("serialize List<String> 10x16B-10kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// 100 Random strings of size between 16B and 1kB
let value = (0..100)
.map(|_| {
let size = rand::thread_rng().gen_range(16..1024);
Alphanumeric.sample_string(&mut rand::thread_rng(), size)
})
.map(String::from)
.collect::<Vec<_>>();
c.bench_function("serialize List<String> 100x16B-10kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// 1000 Random strings of size between 16B and 1kB
let value = (0..1000)
.map(|_| {
let size = rand::thread_rng().gen_range(16..1024);
Alphanumeric.sample_string(&mut rand::thread_rng(), size)
})
.map(String::from)
.collect::<Vec<_>>();
c.bench_function("serialize List<String> 1000x16B-10kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// Map of 10 u64 -> u64
let value = (0..10)
.map(|_| {
Expand Down Expand Up @@ -396,54 +360,6 @@ fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("serialize Map<String, String> 1000x16B", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// Map of 10 random String (16B-1kB) -> random String (16B-1kB)
let value = (0..10)
.map(|_| {
let key_size = rand::thread_rng().gen_range(16..1024);
let key = Alphanumeric.sample_string(&mut rand::thread_rng(), key_size);
let key = String::from(key);
let value_size = rand::thread_rng().gen_range(16..1024);
let value = Alphanumeric.sample_string(&mut rand::thread_rng(), value_size);
let value = String::from(value);
(key, value)
})
.collect::<std::collections::HashMap<_, _>>();
c.bench_function("serialize Map<String, String> 10x16B-1kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// Map of 100 random String (16B-1kB) -> random String (16B-1kB)
let value = (0..100)
.map(|_| {
let key_size = rand::thread_rng().gen_range(16..1024);
let key = Alphanumeric.sample_string(&mut rand::thread_rng(), key_size);
let key = String::from(key);
let value_size = rand::thread_rng().gen_range(16..1024);
let value = Alphanumeric.sample_string(&mut rand::thread_rng(), value_size);
let value = String::from(value);
(key, value)
})
.collect::<std::collections::HashMap<_, _>>();
c.bench_function("serialize Map<String, String> 100x16B-1kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});

// Map of 1000 random String (16B-1kB) -> random String (16B-1kB)
let value = (0..1000)
.map(|_| {
let key_size = rand::thread_rng().gen_range(16..1024);
let key = Alphanumeric.sample_string(&mut rand::thread_rng(), key_size);
let key = String::from(key);
let value_size = rand::thread_rng().gen_range(16..1024);
let value = Alphanumeric.sample_string(&mut rand::thread_rng(), value_size);
let value = String::from(value);
(key, value)
})
.collect::<std::collections::HashMap<_, _>>();
c.bench_function("serialize Map<String, String> 1000x16B-1kB", |b| {
b.iter(|| serde_amqp::to_vec(black_box(&value)).unwrap())
});
}

criterion_group!(benches, criterion_benchmark);
Expand Down
Loading

0 comments on commit 269127d

Please sign in to comment.