diff --git a/Cargo.toml b/Cargo.toml index b421b18..97bcc41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,12 +6,15 @@ edition = "2021" publish = false [dependencies] + getopts = "0.2" jemallocator = "0.5" rustc-serialize = { version = "0.3", optional = true } serde = { version = "1.0", features = ["derive"], optional = true } serde_json = { version = "1.0", optional = true } -simd-json = { version = "0.12", optional = true } +time = "0.3" +simd-json = { version = "0.13", optional = true } +simd-json-derive = { version = "0.13", optional = true } [features] default = ["performance", "all-libs", "all-files"] @@ -19,7 +22,7 @@ all-libs = ["lib-serde", "lib-rustc-serialize", "lib-simd-json"] all-files = ["file-canada", "file-citm-catalog", "file-twitter"] performance = ["parse-dom", "stringify-dom", "parse-struct", "stringify-struct"] lib-serde = ["serde", "serde_json"] -lib-simd-json = ["serde", "simd-json"] +lib-simd-json = ["serde", "simd-json", "simd-json-derive"] lib-rustc-serialize = ["rustc-serialize"] file-canada = [] file-citm-catalog = [] diff --git a/README.md b/README.md index 1d9b97f..893218a 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ are: - [serde\_json] 1.0.72 - [rustc-serialize] 0.3.24 -- [simd-json] 0.4.11 (this requires a modern x86 CPU for good results) +- [simd-json] 0.7.0 (this requires a modern x86 CPU for good results) [nativejson-benchmark]: https://github.com/miloyip/nativejson-benchmark [serde\_json]: https://github.com/serde-rs/json [rustc-serialize]: https://github.com/rust-lang-nursery/rustc-serialize -[simd-json]: https://github.com/Licenser/simdjson-rs +[simd-json]: https://github.com/simd-lite/simd-json #### `$ cargo run --release` diff --git a/src/canada.rs b/src/canada.rs index d1114c7..d2aec7e 100644 --- a/src/canada.rs +++ b/src/canada.rs @@ -6,26 +6,56 @@ use std::collections::BTreeMap as Map; pub type Canada = FeatureCollection; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct FeatureCollection { - #[cfg_attr(feature = "serde", serde(rename = "type"))] + #[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(rename = "type") + )] pub obj_type: ObjType, pub features: Vec, } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Feature { - #[cfg_attr(feature = "serde", serde(rename = "type"))] + #[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(rename = "type") + )] pub obj_type: ObjType, pub properties: Map, pub geometry: Geometry, } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Geometry { - #[cfg_attr(feature = "serde", serde(rename = "type"))] + #[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(rename = "type") + )] pub obj_type: ObjType, pub coordinates: Vec>, } diff --git a/src/color.rs b/src/color.rs index ffcf22e..46d03bf 100644 --- a/src/color.rs +++ b/src/color.rs @@ -12,7 +12,7 @@ use serde::de::{self, Deserialize, Deserializer, Unexpected}; #[cfg(feature = "serde")] use serde::ser::{Serialize, Serializer}; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct Color(u32); #[cfg(any(feature = "serde", feature = "lib-rustc-serialize"))] @@ -58,6 +58,17 @@ impl Serialize for Color { } } +#[cfg(feature = "lib-simd-json")] +impl simd_json_derive::Serialize for Color { + fn json_write(&self, writer: &mut W) -> std::io::Result<()> + where + W: std::io::Write, + { + let mut buf = MaybeUninit::uninit(); + self.as_str(&mut buf).json_write(writer) + } +} + #[cfg(feature = "serde")] impl<'de> Deserialize<'de> for Color { fn deserialize(deserializer: D) -> Result @@ -88,6 +99,29 @@ impl<'de> Deserialize<'de> for Color { } } +#[cfg(feature = "lib-simd-json")] +impl<'input> ::simd_json_derive::Deserialize<'input> for Color { + #[inline] + fn from_tape(tape: &mut ::simd_json_derive::Tape<'input>) -> simd_json::Result + where + Self: std::marker::Sized + 'input, + { + if let Some(::simd_json::Node::String(s)) = tape.next() { + if let Ok(hex) = u32::from_str_radix(s, 16) { + Ok(Color(hex)) + } else { + dbg!(Err(::simd_json::Error::generic( + simd_json::ErrorType::ExpectedString, + ))) + } + } else { + dbg!(Err(::simd_json::Error::generic( + simd_json::ErrorType::ExpectedString, + ))) + } + } +} + #[cfg(feature = "lib-rustc-serialize")] impl Encodable for Color { fn encode(&self, s: &mut S) -> Result<(), S::Error> diff --git a/src/copy/citm_catalog.rs b/src/copy/citm_catalog.rs index 48045ef..19e8355 100644 --- a/src/copy/citm_catalog.rs +++ b/src/copy/citm_catalog.rs @@ -6,11 +6,18 @@ use std::collections::BTreeMap as Map; use crate::empty; use crate::prim_str::PrimStr; -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct CitmCatalog { pub area_names: Map, pub audience_sub_category_names: Map, @@ -28,11 +35,18 @@ pub struct CitmCatalog { pub type Id = u32; pub type IdStr = PrimStr; -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Event { pub description: (), pub id: Id, @@ -44,11 +58,18 @@ pub struct Event { pub topic_ids: Vec, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Performance { pub event_id: Id, pub id: Id, @@ -61,32 +82,53 @@ pub struct Performance { pub venue_code: String, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Price { pub amount: u32, pub audience_sub_category_id: Id, pub seat_category_id: Id, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct SeatCategory { pub areas: Vec, pub seat_category_id: Id, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr( - feature = "serde", + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), serde(deny_unknown_fields, rename_all = "camelCase") )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Area { pub area_id: Id, pub block_ids: empty::Array, diff --git a/src/copy/twitter.rs b/src/copy/twitter.rs index fec8f68..1cd5fb3 100644 --- a/src/copy/twitter.rs +++ b/src/copy/twitter.rs @@ -7,12 +7,22 @@ use crate::color::Color; use crate::empty; use crate::prim_str::PrimStr; -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Twitter { pub statuses: Vec, pub search_metadata: SearchMetadata, @@ -23,12 +33,22 @@ pub type ShortId = u32; pub type LongIdStr = PrimStr; pub type ShortIdStr = PrimStr; -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Status { pub metadata: Metadata, pub created_at: String, @@ -57,23 +77,43 @@ pub struct Status { pub lang: LanguageCode, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Metadata { pub result_type: ResultType, pub iso_language_code: LanguageCode, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct User { pub id: ShortId, pub id_str: ShortIdStr, @@ -117,33 +157,63 @@ pub struct User { pub notifications: bool, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct UserEntities { pub url: Option, pub description: UserEntitiesDescription, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct UserUrl { pub urls: Vec, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Url { pub url: String, pub expanded_url: String, @@ -151,22 +221,42 @@ pub struct Url { pub indices: Indices, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct UserEntitiesDescription { pub urls: Vec, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct StatusEntities { pub hashtags: Vec, pub symbols: empty::Array, @@ -175,23 +265,43 @@ pub struct StatusEntities { pub media: Option>, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Hashtag { pub text: String, pub indices: Indices, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct UserMention { pub screen_name: String, pub name: String, @@ -200,8 +310,18 @@ pub struct UserMention { pub indices: Indices, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Media { pub id: LongId, pub id_str: LongIdStr, @@ -211,19 +331,32 @@ pub struct Media { pub url: String, pub display_url: String, pub expanded_url: String, - #[cfg_attr(feature = "serde", serde(rename = "type"))] + #[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(rename = "type") + )] pub media_type: String, pub sizes: Sizes, pub source_status_id: Option, pub source_status_id_str: Option, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Sizes { pub medium: Size, pub small: Size, @@ -231,12 +364,22 @@ pub struct Sizes { pub large: Size, } -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct Size { pub w: u16, pub h: u16, @@ -245,12 +388,22 @@ pub struct Size { pub type Indices = (u8, u8); -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + derive(Serialize, Deserialize) +)] +#[cfg_attr( + any(feature = "serde", feature = "lib-simd-json"), + serde(deny_unknown_fields) +)] #[cfg_attr( feature = "lib-rustc-serialize", derive(RustcEncodable, RustcDecodable) )] +#[cfg_attr( + feature = "lib-simd-json", + derive(simd_json_derive::Serialize, simd_json_derive::Deserialize) +)] pub struct SearchMetadata { pub completed_in: f32, pub max_id: LongId, diff --git a/src/empty.rs b/src/empty.rs index 59ed200..c0b8d1d 100644 --- a/src/empty.rs +++ b/src/empty.rs @@ -45,6 +45,32 @@ impl<'de> Deserialize<'de> for Array { } } +#[cfg(feature = "lib-simd-json")] +impl simd_json_derive::Serialize for Array { + fn json_write(&self, writer: &mut W) -> std::io::Result<()> + where + W: std::io::Write, + { + writer.write_all(b"[]") + } +} + +impl<'input> simd_json_derive::Deserialize<'input> for Array { + #[inline] + fn from_tape(tape: &mut simd_json_derive::Tape<'input>) -> simd_json::Result + where + Self: std::marker::Sized + 'input, + { + if let Some(simd_json::Node::Array { len: 0, .. }) = tape.next() { + Ok(Self) + } else { + Err(simd_json::Error::generic( + simd_json::ErrorType::ExpectedArray, + )) + } + } +} + #[cfg(feature = "lib-rustc-serialize")] impl Encodable for Array { fn encode(&self, s: &mut S) -> Result<(), S::Error> diff --git a/src/enums.rs b/src/enums.rs index 856b738..a97f876 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -1,12 +1,12 @@ #[macro_export] macro_rules! enum_str { ($name:ident { $($variant:ident($str:expr), )* }) => { - #[derive(Clone, Copy)] + #[derive(Clone, Copy, Debug)] pub enum $name { $($variant,)* } - #[cfg(any(feature = "serde", feature = "lib-rustc-serialize"))] + #[cfg(any(feature = "lib-simd-json", feature = "lib-serde", feature = "lib-rustc-serialize"))] impl $name { fn as_str(self) -> &'static str { match self { @@ -52,6 +52,40 @@ macro_rules! enum_str { } } + #[cfg(feature = "lib-simd-json")] + impl ::simd_json_derive::Serialize for $name { + #[inline] + fn json_write(&self, writer: &mut W) -> std::io::Result<()> + where W: std::io::Write + { + self.as_str().json_write(writer) + } + } + + #[cfg(feature = "lib-simd-json")] + impl<'input> ::simd_json_derive::Deserialize<'input> for $name { + #[inline] + fn from_tape(tape: &mut ::simd_json_derive::Tape<'input>) -> simd_json::Result + where + Self: std::marker::Sized + 'input, + { + if let Some(::simd_json::Node::String(s)) = tape.next() { + match s { + $( $str => Ok($name::$variant), )* + _ => Err(::simd_json::Error::generic( + simd_json::ErrorType::ExpectedString, + )), + } + + } else { + Err(::simd_json::Error::generic( + simd_json::ErrorType::ExpectedString, + )) + } + } + } + + #[cfg(feature = "lib-rustc-serialize")] impl ::rustc_serialize::Encodable for $name { fn encode(&self, s: &mut S) -> Result<(), S::Error> diff --git a/src/main.rs b/src/main.rs index 4cd8c65..db495a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -131,7 +131,9 @@ macro_rules! bench_file_simd_json { path: $path:expr, structure: $structure:ty, } => { + let num_trials = num_trials().unwrap_or(256); + let mut buffers = simd_json::Buffers::new(4096); print!("{:22}", $path); io::stdout().flush().unwrap(); @@ -150,7 +152,7 @@ macro_rules! bench_file_simd_json { for _ in 0..num_trials { data.as_mut_slice().clone_from_slice(contents.as_slice()); let mut timer = benchmark.start(); - let _parsed = simd_json_parse_dom(&mut data).unwrap(); + let _parsed = simd_json_parse_dom(&mut data, &mut buffers).unwrap(); timer.stop(); } let dur = benchmark.min_elapsed(); @@ -164,12 +166,12 @@ macro_rules! bench_file_simd_json { { let len = contents.len(); let mut data = contents.clone(); - let dom = simd_json_parse_dom(&mut data).unwrap(); + let dom = simd_json_parse_dom(&mut data, &mut buffers).unwrap(); let dur = timer::bench_with_buf(num_trials, len, |out| { - simd_json::Writable::write(&dom, out).unwrap() + simd_json::prelude::Writable::write(&dom, out).unwrap() }); let mut serialized = Vec::new(); - simd_json::Writable::write(&dom, &mut serialized).unwrap(); + simd_json::prelude::Writable::write(&dom, &mut serialized).unwrap(); print!("{:6} MB/s", throughput(dur, serialized.len())); io::stdout().flush().unwrap(); } @@ -184,7 +186,7 @@ macro_rules! bench_file_simd_json { for _ in 0..num_trials { data.as_mut_slice().clone_from_slice(contents.as_slice()); let mut timer = benchmark.start(); - let _parsed: $structure = simd_json_parse_struct(&mut data).unwrap(); + let _parsed: $structure = simd_json_parse_struct(&mut data, &mut buffers).unwrap(); timer.stop(); } let dur = benchmark.min_elapsed(); @@ -192,6 +194,22 @@ macro_rules! bench_file_simd_json { io::stdout().flush().unwrap(); } + #[cfg(feature = "stringify-struct")] + { + use simd_json_derive::Serialize; + let len = contents.len(); + let mut data = contents.clone(); + let parsed: $structure = simd_json_parse_struct(&mut data, &mut buffers).unwrap(); + let dur = timer::bench_with_buf(num_trials, len, |out| { + parsed.json_write(out).unwrap(); + }); + let mut serialized = Vec::new(); + parsed.json_write(&mut serialized).unwrap(); + + print!("{:6} MB/s", throughput(dur, serialized.len())); + io::stdout().flush().unwrap(); + } + println!(); } } @@ -292,17 +310,34 @@ where feature = "lib-simd-json", any(feature = "parse-dom", feature = "stringify-dom") ))] -fn simd_json_parse_dom(bytes: &mut [u8]) -> simd_json::Result { - simd_json::to_borrowed_value(bytes) +fn simd_json_parse_dom<'input>( + bytes: &'input mut [u8], + buffers: &mut simd_json::Buffers, +) -> simd_json::Result> { + simd_json::to_borrowed_value_with_buffers(bytes, buffers) } +// #[cfg(all( +// feature = "lib-simd-json", +// any(feature = "parse-struct", feature = "stringify-struct") +// ))] +// fn simd_json_parse_struct<'de, T>(bytes: &'de mut [u8]) -> simd_json::Result +// where +// T: serde::Deserialize<'de>, +// { +// simd_json::serde::from_slice(bytes) +// } + #[cfg(all( feature = "lib-simd-json", any(feature = "parse-struct", feature = "stringify-struct") ))] -fn simd_json_parse_struct<'de, T>(bytes: &'de mut [u8]) -> simd_json::Result +fn simd_json_parse_struct<'de, T>( + bytes: &'de mut [u8], + buffers: &mut simd_json::Buffers, +) -> simd_json::Result where - T: serde::Deserialize<'de>, + T: simd_json_derive::Deserialize<'de> + 'de, { - simd_json::serde::from_slice(bytes) + T::from_slice_with_buffers(bytes, buffers) } diff --git a/src/prim_str.rs b/src/prim_str.rs index 6d34daf..79b5d6e 100644 --- a/src/prim_str.rs +++ b/src/prim_str.rs @@ -65,6 +65,53 @@ where } } +#[cfg(feature = "lib-simd-json")] +impl simd_json_derive::Serialize for PrimStr +where + T: Copy + Ord + Display + FromStr, +{ + fn json_write(&self, writer: &mut W) -> std::io::Result<()> + where + W: std::io::Write, + { + write!(writer, r#""{}""#, self.0) + } +} + +#[cfg(feature = "lib-simd-json")] +impl simd_json_derive::SerializeAsKey for PrimStr +where + T: Copy + Ord + Display + FromStr, +{ + fn json_write(&self, writer: &mut W) -> std::io::Result<()> + where + W: std::io::Write, + { + write!(writer, r#""{}""#, self.0) + } +} + +impl<'input, T> simd_json_derive::Deserialize<'input> for PrimStr +where + T: Copy + Ord + Display + FromStr, +{ + #[inline] + fn from_tape(tape: &mut simd_json_derive::Tape<'input>) -> simd_json::Result + where + Self: std::marker::Sized + 'input, + { + if let Some(simd_json::Node::String(s)) = tape.next() { + Ok(PrimStr(FromStr::from_str(s).map_err(|_e| { + simd_json::Error::generic(simd_json::ErrorType::Serde("not a number".into())) + })?)) + } else { + Err(simd_json::Error::generic( + simd_json::ErrorType::ExpectedNull, + )) + } + } +} + #[cfg(feature = "lib-rustc-serialize")] impl Encodable for PrimStr where