diff --git a/viz-core/src/response.rs b/viz-core/src/response.rs index 4981e9c..6560c91 100644 --- a/viz-core/src/response.rs +++ b/viz-core/src/response.rs @@ -68,8 +68,16 @@ pub trait ResponseExt: private::Sealed + Sized { where T: serde::Serialize, { - serde_json::to_vec(&body) - .map(|buf| Self::with(Full::new(buf.into()), mime::APPLICATION_JSON.as_ref())) + use bytes::{BufMut, BytesMut}; + + let mut buf = BytesMut::with_capacity(128).writer(); + serde_json::to_writer(&mut buf, &body) + .map(|()| { + Response::with( + Full::new(buf.into_inner().freeze()), + mime::APPLICATION_JSON.as_ref(), + ) + }) .map_err(crate::types::PayloadError::Json) } diff --git a/viz-core/tests/response.rs b/viz-core/tests/response.rs index a9e8de4..ea701a4 100644 --- a/viz-core/tests/response.rs +++ b/viz-core/tests/response.rs @@ -1,3 +1,8 @@ +#![feature(test)] + +extern crate test; +use test::Bencher; + use futures_util::{stream, Stream, StreamExt}; use headers::{ContentDisposition, ContentType, HeaderMapExt}; use http_body_util::{BodyExt, Full}; @@ -129,3 +134,105 @@ async fn response_ext() -> Result<()> { fn response_ext_panic() { Response::redirect_with_status("/oauth", StatusCode::OK); } + +#[cfg(all(feature = "json", not(miri)))] +#[bench] +fn response_json_with_to_vec(b: &mut Bencher) { + use mime; + use viz_core::types::PayloadError; + + #[derive(Serialize)] + struct Message { + message: &'static str, + } + + b.iter(|| { + let body = Message { + message: "Hello, World!", + }; + + let body = serde_json::to_vec(&body).map_err(PayloadError::Json)?; + Ok::(Response::with( + Full::from(body), + mime::APPLICATION_JSON.as_ref(), + )) + }); +} + +#[cfg(all(feature = "json", not(miri)))] +#[bench] +fn response_json_with_map_to_vec(b: &mut Bencher) { + use mime; + use viz_core::types::PayloadError; + + #[derive(Serialize)] + struct Message { + message: &'static str, + } + + b.iter(|| { + let body = Message { + message: "Hello, World!", + }; + + serde_json::to_vec(&body) + .map(|buf| Response::with(Full::new(buf.into()), mime::APPLICATION_JSON.as_ref())) + .map_err(PayloadError::Json) + }); +} + +#[cfg(all(feature = "json", not(miri)))] +#[bench] +fn response_json_with_to_writer(b: &mut Bencher) { + use bytes::{BufMut, BytesMut}; + use mime; + use viz_core::types::PayloadError; + + #[derive(Serialize)] + struct Message { + message: &'static str, + } + + b.iter(|| { + let body = Message { + message: "Hello, World!", + }; + + let mut buf = BytesMut::with_capacity(128).writer(); + let () = serde_json::to_writer(&mut buf, &body).map_err(PayloadError::Json)?; + + Ok::(Response::with( + Full::new(buf.into_inner().freeze()), + mime::APPLICATION_JSON.as_ref(), + )) + }); +} + +#[cfg(all(feature = "json", not(miri)))] +#[bench] +fn response_json_with_map_to_writer(b: &mut Bencher) { + use bytes::{BufMut, BytesMut}; + use mime; + use viz_core::types::PayloadError; + + #[derive(Serialize)] + struct Message { + message: &'static str, + } + + b.iter(|| { + let body = Message { + message: "Hello, World!", + }; + + let mut buf = BytesMut::with_capacity(128).writer(); + serde_json::to_writer(&mut buf, &body) + .map(|()| { + Response::with( + Full::new(buf.into_inner().freeze()), + mime::APPLICATION_JSON.as_ref(), + ) + }) + .map_err(PayloadError::Json) + }); +}