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:
parent
f65529aa67
commit
94c8ecfaaa
5 changed files with 69 additions and 18 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,6 +19,7 @@ pub enum Error {
|
|||
ExpectedBuffer,
|
||||
|
||||
ExpectedUtf8,
|
||||
ExpectedLatin1,
|
||||
|
||||
LengthMismatch,
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Add table
Reference in a new issue