0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

perf(serde_v8): optimize ByteString deserialization (#13853)

This commit is contained in:
Aaron O'Mullan 2022-03-07 11:12:36 +01:00 committed by GitHub
parent f65529aa67
commit 94c8ecfaaa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 18 deletions

View file

@ -4,6 +4,7 @@ use bencher::{benchmark_group, benchmark_main, Bencher};
use serde::Deserialize;
use serde_v8::utils::{js_exec, v8_do};
use serde_v8::ByteString;
#[derive(Debug, Deserialize, PartialEq)]
struct MathOp {
@ -135,6 +136,25 @@ fn de_tuple_v8_opt(b: &mut Bencher) {
});
}
fn de_bstr_v8_12_b(b: &mut Bencher) {
dedo(r#""hello world\n""#, |scope, v| {
b.iter(move || {
let _: ByteString = serde_v8::from_v8(scope, v).unwrap();
});
});
}
fn de_bstr_v8_1024_b(b: &mut Bencher) {
dedo(
r#""hello world\n".repeat(1e2).slice(0, 1024)"#,
|scope, v| {
b.iter(move || {
let _: ByteString = serde_v8::from_v8(scope, v).unwrap();
});
},
);
}
benchmark_group!(
benches,
de_struct_v8,
@ -152,6 +172,8 @@ benchmark_group!(
de_tuple_v8,
de_tuple_json,
de_tuple_v8_opt,
de_bstr_v8_12_b,
de_bstr_v8_1024_b,
);
benchmark_main!(benches);

View file

@ -4,6 +4,7 @@ use bencher::{benchmark_group, benchmark_main, Bencher};
use serde::Serialize;
use serde_v8::utils::v8_do;
use serde_v8::ByteString;
#[derive(Serialize)]
struct MathOp {
@ -87,6 +88,26 @@ fn ser_struct_v8_manual(b: &mut Bencher) {
});
}
fn ser_bstr_12_b(b: &mut Bencher) {
serdo(|scope| {
let bstr = ByteString("hello world\n".to_owned().into_bytes());
b.iter(|| {
let _ = serde_v8::to_v8(scope, &bstr).unwrap();
});
});
}
fn ser_bstr_1024_b(b: &mut Bencher) {
serdo(|scope| {
let mut s = "hello world\n".repeat(100);
s.truncate(1024);
let bstr = ByteString(s.into_bytes());
b.iter(|| {
let _ = serde_v8::to_v8(scope, &bstr).unwrap();
});
});
}
benchmark_group!(
benches,
ser_struct_v8,
@ -102,5 +123,7 @@ benchmark_group!(
ser_tuple_v8,
ser_tuple_json,
ser_struct_v8_manual,
ser_bstr_12_b,
ser_bstr_1024_b,
);
benchmark_main!(benches);

View file

@ -370,25 +370,25 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
// Magic ByteString
if name == magic::bytestring::NAME {
if let Some(v8_string) = self.input.to_string(self.scope) {
if v8_string.contains_only_onebyte() {
let mut buffer: Vec<u8> = vec![0u8; v8_string.length()];
let written = v8_string.write_one_byte(
self.scope,
&mut buffer,
0,
v8::WriteOptions::NO_NULL_TERMINATION,
);
assert!(written == v8_string.length());
return visitor.visit_byte_buf(buffer);
} else {
return Err(Error::Message(
"Expected a valid ByteString.".to_string(),
));
}
} else {
return Err(Error::ExpectedString);
let v8str = v8::Local::<v8::String>::try_from(self.input)
.map_err(|_| Error::ExpectedString)?;
if !v8str.contains_only_onebyte() {
return Err(Error::ExpectedLatin1);
}
let len = v8str.length();
let mut buffer = Vec::with_capacity(len);
#[allow(clippy::uninit_vec)]
unsafe {
buffer.set_len(len);
}
let written = v8str.write_one_byte(
self.scope,
&mut buffer,
0,
v8::WriteOptions::NO_NULL_TERMINATION,
);
assert!(written == len);
return visitor.visit_byte_buf(buffer);
}
// Regular struct

View file

@ -19,6 +19,7 @@ pub enum Error {
ExpectedBuffer,
ExpectedUtf8,
ExpectedLatin1,
LengthMismatch,
}

View file

@ -3,6 +3,7 @@ use serde::Deserialize;
use serde_v8::utils::{js_exec, v8_do};
use serde_v8::Buffer;
use serde_v8::ByteString;
use serde_v8::Error;
#[derive(Debug, Deserialize, PartialEq)]
@ -311,3 +312,7 @@ detest!(
b: "".into()
}
);
detest!(de_bstr, ByteString, "'hello'", ByteString("hello".into()));
defail!(defail_bstr, ByteString, "'👋bye'", |e| e
== Err(Error::ExpectedLatin1));