From a5ca5c814f833fbe70151feb3bf4499704088a28 Mon Sep 17 00:00:00 2001 From: Piotr Sikora Date: Sun, 27 Oct 2024 16:52:42 -0400 Subject: [PATCH] Pass slice instead of Vec during map serialization. Before: utils::bench_serialize_map ... bench: 66.87 ns/iter (+/- 1.33) utils::bench_serialize_map_bytes ... bench: 69.42 ns/iter (+/- 1.45) After: utils::bench_serialize_map ... bench: 55.84 ns/iter (+/- 1.16) utils::bench_serialize_map_bytes ... bench: 56.03 ns/iter (+/- 1.19) Note that this is changed only in the private functions to avoid breaking the public API. Signed-off-by: Piotr Sikora --- src/hostcalls.rs | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/hostcalls.rs b/src/hostcalls.rs index 788de41..42370b3 100644 --- a/src/hostcalls.rs +++ b/src/hostcalls.rs @@ -190,7 +190,7 @@ extern "C" { } pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> { - let serialized_map = utils::serialize_map(map); + let serialized_map = utils::serialize_map(&map); unsafe { match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) { Status::Ok => Ok(()), @@ -200,7 +200,7 @@ pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> } pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Result<(), Status> { - let serialized_map = utils::serialize_map_bytes(map); + let serialized_map = utils::serialize_map_bytes(&map); unsafe { match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) { Status::Ok => Ok(()), @@ -710,7 +710,7 @@ pub fn send_http_response( headers: Vec<(&str, &str)>, body: Option<&[u8]>, ) -> Result<(), Status> { - let serialized_headers = utils::serialize_map(headers); + let serialized_headers = utils::serialize_map(&headers); unsafe { match proxy_send_local_response( status_code, @@ -733,7 +733,7 @@ pub fn send_grpc_response( grpc_status_message: Option<&str>, custom_metadata: Vec<(&str, &[u8])>, ) -> Result<(), Status> { - let serialized_custom_metadata = utils::serialize_map_bytes(custom_metadata); + let serialized_custom_metadata = utils::serialize_map_bytes(&custom_metadata); unsafe { match proxy_send_local_response( 200, @@ -773,8 +773,8 @@ pub fn dispatch_http_call( trailers: Vec<(&str, &str)>, timeout: Duration, ) -> Result { - let serialized_headers = utils::serialize_map(headers); - let serialized_trailers = utils::serialize_map(trailers); + let serialized_headers = utils::serialize_map(&headers); + let serialized_trailers = utils::serialize_map(&trailers); let mut return_token: u32 = 0; unsafe { match proxy_http_call( @@ -826,7 +826,7 @@ pub fn dispatch_grpc_call( timeout: Duration, ) -> Result { let mut return_callout_id = 0; - let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata); unsafe { match proxy_grpc_call( upstream_name.as_ptr(), @@ -874,7 +874,7 @@ pub fn open_grpc_stream( initial_metadata: Vec<(&str, &[u8])>, ) -> Result { let mut return_stream_id = 0; - let serialized_initial_metadata = utils::serialize_map_bytes(initial_metadata); + let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata); unsafe { match proxy_grpc_stream( upstream_name.as_ptr(), @@ -1159,18 +1159,18 @@ mod utils { bytes } - pub(super) fn serialize_map(map: Vec<(&str, &str)>) -> Bytes { + pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes { let mut size: usize = 4; - for (name, value) in &map { + for (name, value) in map { size += name.len() + value.len() + 10; } let mut bytes: Bytes = Vec::with_capacity(size); bytes.extend_from_slice(&(map.len() as u32).to_le_bytes()); - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(&(name.len() as u32).to_le_bytes()); bytes.extend_from_slice(&(value.len() as u32).to_le_bytes()); } - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(name.as_bytes()); bytes.push(0); bytes.extend_from_slice(value.as_bytes()); @@ -1179,18 +1179,18 @@ mod utils { bytes } - pub(super) fn serialize_map_bytes(map: Vec<(&str, &[u8])>) -> Bytes { + pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes { let mut size: usize = 4; - for (name, value) in &map { + for (name, value) in map { size += name.len() + value.len() + 10; } let mut bytes: Bytes = Vec::with_capacity(size); bytes.extend_from_slice(&(map.len() as u32).to_le_bytes()); - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(&(name.len() as u32).to_le_bytes()); bytes.extend_from_slice(&(value.len() as u32).to_le_bytes()); } - for (name, value) in &map { + for (name, value) in map { bytes.extend_from_slice(name.as_bytes()); bytes.push(0); bytes.extend_from_slice(value); @@ -1290,14 +1290,14 @@ mod utils { #[test] fn test_serialize_map() { - let serialized_map = serialize_map(MAP.to_vec()); + let serialized_map = serialize_map(MAP); assert_eq!(serialized_map, SERIALIZED_MAP); } #[test] fn test_serialize_map_bytes() { let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect(); - let serialized_map = serialize_map_bytes(map); + let serialized_map = serialize_map_bytes(&map); assert_eq!(serialized_map, SERIALIZED_MAP); } @@ -1326,7 +1326,7 @@ mod utils { fn bench_serialize_map(b: &mut Bencher) { let map = MAP.to_vec(); b.iter(|| { - serialize_map(test::black_box(map.clone())); + serialize_map(test::black_box(&map)); }); } @@ -1335,7 +1335,7 @@ mod utils { fn bench_serialize_map_bytes(b: &mut Bencher) { let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect(); b.iter(|| { - serialize_map_bytes(test::black_box(map.clone())); + serialize_map_bytes(test::black_box(&map)); }); }