From f46d5a9973c1db090f9502ef275e7010916a92a0 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 14 Jun 2014 10:48:01 -0700 Subject: [PATCH] Add some serialization benchmarks test bench_enum::bench_decoder_dog ... bench: 110 ns/iter (+/- 3) test bench_enum::bench_decoder_frog ... bench: 330 ns/iter (+/- 13) test bench_enum::bench_deserializer_dog ... bench: 116 ns/iter (+/- 1) test bench_enum::bench_deserializer_frog ... bench: 310 ns/iter (+/- 31) test bench_map::bench_decoder_000 ... bench: 528 ns/iter (+/- 43) test bench_map::bench_decoder_003 ... bench: 2330 ns/iter (+/- 168) test bench_map::bench_decoder_100 ... bench: 69124 ns/iter (+/- 6764) test bench_map::bench_deserializer_000 ... bench: 790 ns/iter (+/- 73) test bench_map::bench_deserializer_003 ... bench: 2552 ns/iter (+/- 443) test bench_map::bench_deserializer_100 ... bench: 61059 ns/iter (+/- 3776) test bench_struct::bench_decoder_0_0 ... bench: 608 ns/iter (+/- 54) test bench_struct::bench_decoder_1_0 ... bench: 1584 ns/iter (+/- 84) test bench_struct::bench_decoder_1_5 ... bench: 4294 ns/iter (+/- 799) test bench_struct::bench_deserializer_0_0 ... bench: 670 ns/iter (+/- 61) test bench_struct::bench_deserializer_1_0 ... bench: 2035 ns/iter (+/- 153) test bench_struct::bench_deserializer_1_5 ... bench: 4825 ns/iter (+/- 699) test bench_vec::bench_decoder_int_000 ... bench: 20 ns/iter (+/- 1) test bench_vec::bench_decoder_int_003 ... bench: 149 ns/iter (+/- 8) test bench_vec::bench_decoder_int_100 ... bench: 989 ns/iter (+/- 14) test bench_vec::bench_decoder_u8_000 ... bench: 16 ns/iter (+/- 0) test bench_vec::bench_decoder_u8_003 ... bench: 155 ns/iter (+/- 9) test bench_vec::bench_decoder_u8_100 ... bench: 1424 ns/iter (+/- 13) test bench_vec::bench_deserializer_int_000 ... bench: 16 ns/iter (+/- 0) test bench_vec::bench_deserializer_int_003 ... bench: 152 ns/iter (+/- 11) test bench_vec::bench_deserializer_int_100 ... bench: 1015 ns/iter (+/- 64) test bench_vec::bench_deserializer_u8_000 ... bench: 16 ns/iter (+/- 1) test bench_vec::bench_deserializer_u8_003 ... bench: 155 ns/iter (+/- 9) test bench_vec::bench_deserializer_u8_100 ... bench: 1163 ns/iter (+/- 74) test json::bench::bench_decoder_001 ... bench: 3951 ns/iter (+/- 523) test json::bench::bench_decoder_001_streaming ... bench: 2032 ns/iter (+/- 850) test json::bench::bench_decoder_500 ... bench: 1936618 ns/iter (+/- 215448) test json::bench::bench_decoder_500_streaming ... bench: 831512 ns/iter (+/- 17862) test json::bench::bench_deserializer_001 ... bench: 3767 ns/iter (+/- 127) test json::bench::bench_deserializer_001_streaming ... bench: 2070 ns/iter (+/- 67) test json::bench::bench_deserializer_500 ... bench: 1794293 ns/iter (+/- 63726) test json::bench::bench_deserializer_500_streaming ... bench: 919105 ns/iter (+/- 56000) test json::bench::bench_encoder_001 ... bench: 5137 ns/iter (+/- 146) test json::bench::bench_encoder_001_pretty ... bench: 7448 ns/iter (+/- 79) test json::bench::bench_encoder_500 ... bench: 2310173 ns/iter (+/- 33944) test json::bench::bench_encoder_500_pretty ... bench: 3396347 ns/iter (+/- 163104) test json::bench::bench_serializer_001 ... bench: 4009 ns/iter (+/- 412) test json::bench::bench_serializer_001_pretty ... bench: 6499 ns/iter (+/- 58) test json::bench::bench_serializer_500 ... bench: 1721992 ns/iter (+/- 21521) test json::bench::bench_serializer_500_pretty ... bench: 2880591 ns/iter (+/- 146516) --- json.rs | 697 ++++++++++++++++++++++++++++---------------------------- ser.rs | 15 +- 2 files changed, 351 insertions(+), 361 deletions(-) diff --git a/json.rs b/json.rs index 57a2b295..054fb528 100644 --- a/json.rs +++ b/json.rs @@ -71,8 +71,8 @@ fn main() { let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()}; let mut m = io::MemWriter::new(); { - let mut encoder = json::Encoder::new(&mut m as &mut Writer); - match to_encode_object.encode(&mut encoder) { + let mut serializer = json::Serializer::new(&mut m as &mut Writer); + match to_encode_object.encode(&mut serializer) { Ok(()) => (), Err(e) => fail!("json encoding error: {}", e) }; @@ -86,7 +86,7 @@ into a string (String) or buffer (~[u8]): `str_encode(&m)` and `buffer_encode(&m ```rust use serialize::json; let to_encode_object = "example of string to encode".to_string(); -let encoded_str: String = json::Encoder::str_encode(&to_encode_object); +let encoded_str: String = json::Serializer::str_encode(&to_encode_object); ``` JSON API provide an enum `json::Json` and a trait `ToJson` to encode object. @@ -171,7 +171,7 @@ use serialize::{json, Encodable, Decodable}; fn main() { let to_encode_object = TestStruct1 {data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]}; - let encoded_str: String = json::Encoder::str_encode(&to_encode_object); + let encoded_str: String = json::Serializer::str_encode(&to_encode_object); // To deserialize use the `json::from_str` and `json::Decoder` @@ -262,15 +262,15 @@ pub type Object = TreeMap; impl Json { /// Encodes a json value into an io::writer. Uses a single line. pub fn to_writer(&self, wr: &mut Writer) -> EncodeResult { - let mut encoder = Encoder::new(wr); - self.serialize(&mut encoder) + let mut serializer = Serializer::new(wr); + self.serialize(&mut serializer) } /// Encodes a json value into an io::writer. /// Pretty-prints in a more readable format. pub fn to_pretty_writer(&self, wr: &mut Writer) -> EncodeResult { - let mut encoder = PrettyEncoder::new(wr); - self.serialize(&mut encoder) + let mut serializer = PrettySerializer::new(wr); + self.serialize(&mut serializer) } /// Encodes a json value into a string @@ -748,7 +748,7 @@ fn spaces(n: uint) -> String { } #[deriving(Show)] -enum EncoderState { +enum SerializerState { ValueState, SeqState(bool), MapState(bool), @@ -756,16 +756,16 @@ enum EncoderState { } /// A structure for implementing serialization to JSON. -pub struct Encoder<'a> { +pub struct Serializer<'a> { wr: &'a mut Writer, - state_stack: Vec, + state_stack: Vec, } -impl<'a> Encoder<'a> { - /// Creates a new JSON encoder whose output will be written to the writer +impl<'a> Serializer<'a> { + /// Creates a new JSON serializer whose output will be written to the writer /// specified. - pub fn new(wr: &'a mut Writer) -> Encoder<'a> { - Encoder { + pub fn new(wr: &'a mut Writer) -> Serializer<'a> { + Serializer { wr: wr, state_stack: vec!(ValueState), } @@ -774,12 +774,12 @@ impl<'a> Encoder<'a> { /// Encode the specified struct into a json [u8] pub fn buf_encode< 'a, - T: ser::Serializable> + T: ser::Serializable> >(value: &T) -> Vec { let mut wr = MemWriter::new(); { - let mut encoder = Encoder::new(&mut wr); - value.serialize(&mut encoder).unwrap(); + let mut serializer = Serializer::new(&mut wr); + value.serialize(&mut serializer).unwrap(); } wr.unwrap() } @@ -787,9 +787,9 @@ impl<'a> Encoder<'a> { /// Encode the specified struct into a json str pub fn str_encode< 'a, - T: ser::Serializable> + T: ser::Serializable> >(value: &T) -> Result> { - let buf = Encoder::buf_encode(value); + let buf = Serializer::buf_encode(value); String::from_utf8(buf) } @@ -887,7 +887,7 @@ impl<'a> Encoder<'a> { } } -impl<'a> ser::Serializer for Encoder<'a> { +impl<'a> ser::Serializer for Serializer<'a> { fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> { match self.state_stack.pop() { Some(ValueState) => self.serialize_value(token), @@ -899,18 +899,18 @@ impl<'a> ser::Serializer for Encoder<'a> { } } -/// Another encoder for JSON, but prints out human-readable JSON instead of +/// Another serializer for JSON, but prints out human-readable JSON instead of /// compact data -pub struct PrettyEncoder<'a> { +pub struct PrettySerializer<'a> { wr: &'a mut Writer, indent: uint, - state_stack: Vec, + state_stack: Vec, } -impl<'a> PrettyEncoder<'a> { - /// Creates a new encoder whose output will be written to the specified writer - pub fn new(wr: &'a mut Writer) -> PrettyEncoder<'a> { - PrettyEncoder { +impl<'a> PrettySerializer<'a> { + /// Creates a new serializer whose output will be written to the specified writer + pub fn new(wr: &'a mut Writer) -> PrettySerializer<'a> { + PrettySerializer { wr: wr, indent: 0, state_stack: vec!(ValueState), @@ -920,12 +920,12 @@ impl<'a> PrettyEncoder<'a> { /// Encode the specified struct into a json [u8] pub fn buf_encode< 'a, - T: ser::Serializable> + T: ser::Serializable> >(value: &T) -> Vec { let mut wr = MemWriter::new(); { - let mut encoder = PrettyEncoder::new(&mut wr); - value.serialize(&mut encoder).unwrap(); + let mut serializer = PrettySerializer::new(&mut wr); + value.serialize(&mut serializer).unwrap(); } wr.unwrap() } @@ -933,9 +933,9 @@ impl<'a> PrettyEncoder<'a> { /// Encode the specified struct into a json str pub fn str_encode< 'a, - T: ser::Serializable> + T: ser::Serializable> >(value: &T) -> Result> { - let buf = PrettyEncoder::buf_encode(value); + let buf = PrettySerializer::buf_encode(value); String::from_utf8(buf) } @@ -1065,7 +1065,7 @@ impl<'a> PrettyEncoder<'a> { } } -impl<'a> ser::Serializer for PrettyEncoder<'a> { +impl<'a> ser::Serializer for PrettySerializer<'a> { fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> { match self.state_stack.pop() { Some(ValueState) => self.serialize_value(token), @@ -1763,101 +1763,6 @@ impl> de::Deserializer for Parser { } } -/* -/// A Builder consumes a json::Parser to create a generic Json structure. -pub struct Builder { - parser: Parser, - token: Option, -} - -impl> Builder { - /// Create a JSON Builder. - pub fn new(src: T) -> Builder { - Builder { - parser: Parser::new(src), - token: None, - } - } - - // Decode a Json value from a Parser. - pub fn build(&mut self) -> Result { - self.bump(); - let result = self.build_value(); - self.bump(); - match self.token { - None => {} - Some(Error(e)) => { return Err(e); } - ref tok => { fail!("unexpected token {}", tok.clone()); } - } - return result; - } - - fn bump(&mut self) { - self.token = self.parser.next(); - } - - fn build_value(&mut self) -> Result { - return match self.token { - Some(NullValue) => { Ok(Null) } - Some(NumberValue(n)) => { Ok(Number(n)) } - Some(BooleanValue(b)) => { Ok(Boolean(b)) } - Some(StringValue(ref mut s)) => { - let mut temp = String::new(); - swap(s, &mut temp); - Ok(String(temp)) - } - Some(Error(e)) => { Err(e) } - Some(ListStart) => { self.build_list() } - Some(ObjectStart) => { self.build_object() } - Some(ObjectEnd) => { self.parser.error(InvalidSyntax) } - Some(ListEnd) => { self.parser.error(InvalidSyntax) } - None => { self.parser.error(EOFWhileParsingValue) } - } - } - - fn build_list(&mut self) -> Result { - self.bump(); - let mut values = Vec::new(); - - loop { - if self.token == Some(ListEnd) { - return Ok(List(values.move_iter().collect())); - } - match self.build_value() { - Ok(v) => values.push(v), - Err(e) => { return Err(e) } - } - self.bump(); - } - } - - fn build_object(&mut self) -> Result { - self.bump(); - - let mut values = box TreeMap::new(); - - while self.token != None { - match self.token { - Some(ObjectEnd) => { return Ok(Object(values)); } - Some(Error(e)) => { return Err(e); } - None => { break; } - _ => {} - } - let key = match self.parser.stack().top() { - Some(Key(k)) => { k.to_string() } - _ => { fail!("invalid state"); } - }; - match self.build_value() { - Ok(value) => { values.insert(key, value); } - Err(e) => { return Err(e); } - } - self.bump(); - } - return self.parser.error(EOFWhileParsingObject); - } -} -*/ - /// Decodes a json value from an `Iterator`. pub fn from_iter< Iter: Iterator, @@ -2101,12 +2006,12 @@ impl fmt::Show for Json { #[cfg(test)] mod tests { - extern crate test; - use self::test::Bencher; + use std::io; + use std::fmt::Show; + use std::str; + use std::collections::TreeMap; - use serialize::Encodable; - - use super::{Encoder, PrettyEncoder}; + use super::{Serializer, PrettySerializer}; use super::{Json, Null, Boolean, Number, String, List, Object}; use super::{Parser, ParserError, from_iter, from_str}; use super::{JsonDeserializer, from_json, ToJson}; @@ -2126,11 +2031,6 @@ mod tests { use ser::Serializable; use ser; - use std::io; - use std::fmt::Show; - use std::str; - use std::collections::TreeMap; - macro_rules! treemap { ($($k:expr => $v:expr),*) => ({ let mut _m = ::std::collections::TreeMap::new(); @@ -2139,7 +2039,7 @@ mod tests { }) } - #[deriving(PartialEq, Show, Encodable, Decodable)] + #[deriving(PartialEq, Show)] enum Animal { Dog, Frog(String, int) @@ -2205,7 +2105,7 @@ mod tests { } } - #[deriving(PartialEq, Show, Encodable, Decodable)] + #[deriving(PartialEq, Show)] struct Inner { a: (), b: uint, @@ -2292,7 +2192,7 @@ mod tests { } } - #[deriving(PartialEq, Show, Encodable, Decodable)] + #[deriving(PartialEq, Show)] struct Outer { inner: Vec, } @@ -2361,30 +2261,30 @@ mod tests { fn test_encode_ok< 'a, - T: PartialEq + Show + ToJson + ser::Serializable> + T: PartialEq + Show + ToJson + ser::Serializable> >(errors: &[(T, &str)]) { for &(ref value, out) in errors.iter() { let out = out.to_string(); - let s = Encoder::str_encode(value).unwrap(); + let s = Serializer::str_encode(value).unwrap(); assert_eq!(s, out); - let s = Encoder::str_encode(&value.to_json()).unwrap(); + let s = Serializer::str_encode(&value.to_json()).unwrap(); assert_eq!(s, out); } } fn test_pretty_encode_ok< 'a, - T: PartialEq + Show + ToJson + ser::Serializable> + T: PartialEq + Show + ToJson + ser::Serializable> >(errors: &[(T, &str)]) { for &(ref value, out) in errors.iter() { let out = out.to_string(); - let s = PrettyEncoder::str_encode(value).unwrap(); + let s = PrettySerializer::str_encode(value).unwrap(); assert_eq!(s, out); - let s = PrettyEncoder::str_encode(&value.to_json()).unwrap(); + let s = PrettySerializer::str_encode(&value.to_json()).unwrap(); assert_eq!(s, out); } } @@ -2440,8 +2340,23 @@ mod tests { test_pretty_encode_ok([ (vec!(), "[]"), - (vec!(true), "[\n true\n]"), - (vec!(true, false), "[\n true,\n false\n]"), + ( + vec!(true), + concat!( + "[\n", + " true\n", + "]" + ), + ), + ( + vec!(true, false), + concat!( + "[\n", + " true,\n", + " false\n", + "]" + ), + ), ]); let long_test_list = List(vec![ @@ -2461,14 +2376,16 @@ mod tests { test_pretty_encode_ok([ ( long_test_list, - "[\n \ - false,\n \ - null,\n \ - [\n \ - \"foo\\nbar\",\n \ - 3.5\n \ - ]\n\ - ]" + concat!( + "[\n", + " false,\n", + " null,\n", + " [\n", + " \"foo\\nbar\",\n", + " 3.5\n", + " ]\n", + "]" + ) ) ]); } @@ -2488,13 +2405,26 @@ mod tests { test_pretty_encode_ok([ (treemap!(), "{}"), - (treemap!("a".to_string() => true), "{\n \"a\": true\n}"), + ( + treemap!("a".to_string() => true), + concat!( + "{\n", + " \"a\": true\n", + "}" + ), + ), ( treemap!( "a".to_string() => true, "b".to_string() => false ), - "{\n \"a\": true,\n \"b\": false\n}"), + concat!( + "{\n", + " \"a\": true,\n", + " \"b\": false\n", + "}" + ), + ), ]); let complex_obj = Object(treemap!( @@ -2519,16 +2449,18 @@ mod tests { test_pretty_encode_ok([ ( complex_obj.clone(), - "{\n \ - \"b\": [\n \ - {\n \ - \"c\": \"\\f\\r\"\n \ - },\n \ - {\n \ - \"d\": \"\"\n \ - }\n \ - ]\n\ - }" + concat!( + "{\n", + " \"b\": [\n", + " {\n", + " \"c\": \"\\f\\r\"\n", + " },\n", + " {\n", + " \"d\": \"\"\n", + " }\n", + " ]\n", + "}" + ), ) ]); } @@ -2541,10 +2473,25 @@ mod tests { ]); test_pretty_encode_ok([ - (Dog, "{\n \"Dog\": []\n}"), + ( + Dog, + concat!( + "{\n", + " \"Dog\": []\n", + "}" + ), + ), ( Frog("Henry".to_string(), 349), - "{\n \"Frog\": [\n \"Henry\",\n 349\n ]\n}"), + concat!( + "{\n", + " \"Frog\": [\n", + " \"Henry\",\n", + " 349\n", + " ]\n", + "}" + ), + ), ]); } @@ -2567,7 +2514,15 @@ mod tests { test_pretty_encode_ok([ (None, "null"), - (Some(vec!("foo", "bar")), "[\n \"foo\",\n \"bar\"\n]"), + ( + Some(vec!("foo", "bar")), + concat!( + "[\n", + " \"foo\",\n", + " \"bar\"\n", + "]" + ), + ), ]); } @@ -3102,8 +3057,8 @@ mod tests { hm.insert(1, true); let mut mem_buf = MemWriter::new(); { - let mut encoder = Encoder::new(&mut mem_buf as &mut Writer); - hm.serialize(&mut encoder).unwrap(); + let mut serializer = Serializer::new(&mut mem_buf as &mut Writer); + hm.serialize(&mut serializer).unwrap(); } let bytes = mem_buf.unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap(); @@ -3118,8 +3073,8 @@ mod tests { hm.insert(1, true); let mut mem_buf = MemWriter::new(); { - let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut Writer); - hm.serialize(&mut encoder).unwrap() + let mut serializer = PrettySerializer::new(&mut mem_buf as &mut Writer); + hm.serialize(&mut serializer).unwrap() } let bytes = mem_buf.unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap(); @@ -3422,132 +3377,154 @@ mod tests { assert!(stack.get(1) == Key("foo")); } */ +} - fn small_json() -> String { - r#"{ - "a": 1.0, - "b": [ - true, - "foo\nbar", - { "c": {"d": null} } - ] - }"#.to_string() +#[cfg(test)] +mod bench { + use std::collections::TreeMap; + use serialize; + use test::Bencher; + + use super::{Json, Null, Boolean, Number, String, List, Object}; + use super::{Parser, from_str}; + use de; + + macro_rules! treemap { + ($($k:expr => $v:expr),*) => ({ + let mut _m = ::std::collections::TreeMap::new(); + $(_m.insert($k, $v);)* + _m + }) } - #[bench] - fn bench_decoder_streaming_small(b: &mut Bencher) { - use serialize::json; - let src = small_json(); - b.iter( || { - let mut parser = json::Parser::new(src.as_slice().chars()); - assert_eq!(parser.next(), Some(json::ObjectStart)); - assert_eq!(parser.next(), Some(json::NumberValue(1.0))); - assert_eq!(parser.stack().top(), Some(json::Key("a"))); - assert_eq!(parser.next(), Some(json::ListStart)); - assert_eq!(parser.stack().top(), Some(json::Key("b"))); - assert_eq!(parser.next(), Some(json::BooleanValue(true))); - assert_eq!(parser.next(), Some(json::StringValue("foo\nbar".to_string()))); - assert_eq!(parser.next(), Some(json::ObjectStart)); - assert_eq!(parser.next(), Some(json::ObjectStart)); - assert_eq!(parser.stack().top(), Some(json::Key("c"))); - assert_eq!(parser.next(), Some(json::NullValue)); - assert_eq!(parser.stack().top(), Some(json::Key("d"))); - assert_eq!(parser.next(), Some(json::ObjectEnd)); - assert_eq!(parser.next(), Some(json::ObjectEnd)); - assert_eq!(parser.next(), Some(json::ListEnd)); - assert_eq!(parser.next(), Some(json::ObjectEnd)); - assert_eq!(parser.next(), None); - }); - } - - #[bench] - fn bench_deserializer_streaming_small(b: &mut Bencher) { - let src = small_json(); - b.iter( || { - let mut parser = Parser::new(src.as_slice().chars()); - assert_eq!(parser.next(), Some(Ok(de::MapStart(0)))); - assert_eq!(parser.next(), Some(Ok(de::String("a".to_string())))); - assert_eq!(parser.next(), Some(Ok(de::F64(1.0)))); - assert_eq!(parser.next(), Some(Ok(de::String("b".to_string())))); - assert_eq!(parser.next(), Some(Ok(de::SeqStart(0)))); - assert_eq!(parser.next(), Some(Ok(de::Bool(true)))); - assert_eq!(parser.next(), Some(Ok(de::String("foo\nbar".to_string())))); - assert_eq!(parser.next(), Some(Ok(de::MapStart(0)))); - assert_eq!(parser.next(), Some(Ok(de::String("c".to_string())))); - assert_eq!(parser.next(), Some(Ok(de::MapStart(0)))); - assert_eq!(parser.next(), Some(Ok(de::String("d".to_string())))); - assert_eq!(parser.next(), Some(Ok(de::Null))); - assert_eq!(parser.next(), Some(Ok(de::End))); - assert_eq!(parser.next(), Some(Ok(de::End))); - assert_eq!(parser.next(), Some(Ok(de::End))); - assert_eq!(parser.next(), Some(Ok(de::End))); - assert_eq!(parser.next(), None); - }); - } - - #[bench] - fn bench_decoder_small(b: &mut Bencher) { - use serialize::json; - let src = small_json(); - b.iter( || { - let json: json::Json = json::from_str(src.as_slice()).unwrap(); - assert_eq!( - json, - json::Object(box treemap!( - "a".to_string() => json::Number(1.0), - "b".to_string() => json::List(vec!( - json::Boolean(true), - json::String("foo\nbar".to_string()), - json::Object(box treemap!( - "c".to_string() => json::Object(box treemap!( - "d".to_string() => json::Null - )) - )) - )) - )) - ); - }); - } - - #[bench] - fn bench_deserializer_small(b: &mut Bencher) { - let src = small_json(); - b.iter( || { - let json: Json = from_str(src.as_slice()).unwrap(); - assert_eq!( - json, - Object(treemap!( - "a".to_string() => Number(1.0), - "b".to_string() => List(vec!( - Boolean(true), - String("foo\nbar".to_string()), - Object(treemap!( - "c".to_string() => Object(treemap!( - "d".to_string() => Null - )) - )) - )) - )) - ); - }); - } - - fn big_json(count: uint) -> String { - let mut src = "[\n".to_string(); + fn json_str(count: uint) -> String { + let mut src = "[".to_string(); for _ in range(0, count) { - src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": - [1,2,3]},"#); + src.push_str(r#"{"a":true,"b":null,"c":3.1415,"d":"Hello world","e":[1,2,3]},"#); } src.push_str("{}]"); - return src; + src } - #[bench] - fn bench_decoder_streaming_large(b: &mut Bencher) { + fn pretty_json_str(count: uint) -> String { + let mut src = "[\n".to_string(); + for _ in range(0, count) { + src.push_str( + concat!( + " {\n", + " \"a\": true,\n", + " \"b\": null,\n", + " \"c\": 3.1415,\n", + " \"d\": \"Hello world\",\n", + " \"e\": [\n", + " 1,\n", + " 2,\n", + " 3\n", + " ]\n", + " },\n" + ) + ); + } + src.push_str(" {}\n]"); + src + } + + fn encoder_json(count: uint) -> serialize::json::Json { use serialize::json; - let count = 500; - let src = big_json(count); + let mut list = vec!(); + for _ in range(0, count) { + list.push(json::Object(box treemap!( + "a".to_string() => json::Boolean(true), + "b".to_string() => json::Null, + "c".to_string() => json::Number(3.1415), + "d".to_string() => json::String("Hello world".to_string()), + "e".to_string() => json::List(vec!( + json::Number(1.0), + json::Number(2.0), + json::Number(3.0) + )) + ))); + } + list.push(json::Object(box TreeMap::new())); + json::List(list) + } + + fn serializer_json(count: uint) -> Json { + let mut list = vec!(); + for _ in range(0, count) { + list.push(Object(treemap!( + "a".to_string() => Boolean(true), + "b".to_string() => Null, + "c".to_string() => Number(3.1415), + "d".to_string() => String("Hello world".to_string()), + "e".to_string() => List(vec!( + Number(1.0), + Number(2.0), + Number(3.0) + )) + ))); + } + list.push(Object(TreeMap::new())); + List(list) + } + + fn bench_encoder(b: &mut Bencher, count: uint) { + let src = json_str(count); + let json = encoder_json(count); + + b.iter(|| { + assert_eq!(json.to_str(), src); + }); + } + + fn bench_encoder_pretty(b: &mut Bencher, count: uint) { + let src = pretty_json_str(count); + let json = encoder_json(count); + + b.iter(|| { + assert_eq!(json.to_pretty_str(), src); + }); + } + + fn bench_serializer(b: &mut Bencher, count: uint) { + let src = json_str(count); + let json = serializer_json(count); + + b.iter(|| { + assert_eq!(json.to_str(), src); + }); + } + + fn bench_serializer_pretty(b: &mut Bencher, count: uint) { + let src = pretty_json_str(count); + let json = serializer_json(count); + + b.iter(|| { + assert_eq!(json.to_pretty_str(), src); + }); + } + + fn bench_decoder(b: &mut Bencher, count: uint) { + let src = json_str(count); + let json = encoder_json(count); + b.iter(|| { + assert_eq!(json, serialize::json::from_str(src.as_slice()).unwrap()); + }); + } + + fn bench_deserializer(b: &mut Bencher, count: uint) { + let src = json_str(count); + let json = encoder_json(count); + b.iter(|| { + assert_eq!(json, serialize::json::from_str(src.as_slice()).unwrap()); + }); + } + + fn bench_decoder_streaming(b: &mut Bencher, count: uint) { + use serialize::json; + + let src = json_str(count); b.iter( || { let mut parser = json::Parser::new(src.as_slice().chars()); @@ -3583,40 +3560,8 @@ mod tests { }); } - #[bench] - fn bench_decoder_large(b: &mut Bencher) { - use serialize::json; - - let count = 500; - let src = big_json(count); - - let mut list = vec!(); - for _ in range(0, count) { - list.push(json::Object(box treemap!( - "a".to_string() => json::Boolean(true), - "b".to_string() => json::Null, - "c".to_string() => json::Number(3.1415), - "d".to_string() => json::String("Hello world".to_string()), - "e".to_string() => json::List(vec!( - json::Number(1.0), - json::Number(2.0), - json::Number(3.0) - )) - ))); - } - list.push(json::Object(box TreeMap::new())); - let list = json::List(list); - - b.iter( || { - let json: json::Json = json::from_str(src.as_slice()).unwrap(); - assert_eq!(json, list); - }); - } - - #[bench] - fn bench_deserializer_streaming_large(b: &mut Bencher) { - let count = 500; - let src = big_json(count); + fn bench_deserializer_streaming(b: &mut Bencher, count: uint) { + let src = json_str(count); b.iter( || { let mut parser = Parser::new(src.as_slice().chars()); @@ -3651,7 +3596,6 @@ mod tests { assert_eq!(parser.next(), Some(Ok(de::End))); assert_eq!(parser.next(), None); - loop { match parser.next() { None => return, @@ -3663,30 +3607,81 @@ mod tests { } #[bench] - fn bench_deserializer_large(b: &mut Bencher) { - let count = 500; - let src = big_json(count); + fn bench_encoder_001(b: &mut Bencher) { + bench_encoder(b, 1) + } - let mut list = vec!(); - for _ in range(0, count) { - list.push(Object(treemap!( - "a".to_string() => Boolean(true), - "b".to_string() => Null, - "c".to_string() => Number(3.1415), - "d".to_string() => String("Hello world".to_string()), - "e".to_string() => List(vec!( - Number(1.0), - Number(2.0), - Number(3.0) - )) - ))); - } - list.push(Object(TreeMap::new())); - let list = List(list); + #[bench] + fn bench_encoder_500(b: &mut Bencher) { + bench_encoder(b, 500) + } - b.iter( || { - let json: Json = from_str(src.as_slice()).unwrap(); - assert_eq!(json, list); - }); + #[bench] + fn bench_encoder_001_pretty(b: &mut Bencher) { + bench_encoder_pretty(b, 1) + } + + #[bench] + fn bench_encoder_500_pretty(b: &mut Bencher) { + bench_encoder_pretty(b, 500) + } + + #[bench] + fn bench_serializer_001(b: &mut Bencher) { + bench_serializer(b, 1) + } + + #[bench] + fn bench_serializer_500(b: &mut Bencher) { + bench_serializer(b, 500) + } + #[bench] + fn bench_serializer_001_pretty(b: &mut Bencher) { + bench_serializer_pretty(b, 1) + } + + #[bench] + fn bench_serializer_500_pretty(b: &mut Bencher) { + bench_serializer_pretty(b, 500) + } + + #[bench] + fn bench_decoder_001(b: &mut Bencher) { + bench_decoder(b, 1) + } + + #[bench] + fn bench_decoder_500(b: &mut Bencher) { + bench_decoder(b, 500) + } + + #[bench] + fn bench_deserializer_001(b: &mut Bencher) { + bench_deserializer(b, 1) + } + + #[bench] + fn bench_deserializer_500(b: &mut Bencher) { + bench_deserializer(b, 500) + } + + #[bench] + fn bench_decoder_001_streaming(b: &mut Bencher) { + bench_decoder_streaming(b, 1) + } + + #[bench] + fn bench_decoder_500_streaming(b: &mut Bencher) { + bench_decoder_streaming(b, 500) + } + + #[bench] + fn bench_deserializer_001_streaming(b: &mut Bencher) { + bench_deserializer_streaming(b, 1) + } + + #[bench] + fn bench_deserializer_500_streaming(b: &mut Bencher) { + bench_deserializer_streaming(b, 500) } } diff --git a/ser.rs b/ser.rs index aa5d4d2d..a8a45a94 100644 --- a/ser.rs +++ b/ser.rs @@ -208,7 +208,7 @@ mod tests { use serialize::Decoder; - use super::{Token, Int, Uint, Str, Char, Option}; + use super::{Token, Null, Int, Uint, Str, Char, Option}; use super::{TupleStart, StructStart, EnumStart}; use super::{SeqStart, MapStart, End}; use super::{Serializer, Serializable}; @@ -341,8 +341,7 @@ mod tests { #[test] fn test_tokens_null() { let tokens = vec!( - TupleStart(0), - End, + Null, ); let mut serializer = AssertSerializer::new(tokens.move_iter()); @@ -391,11 +390,8 @@ mod tests { fn test_tokens_tuple_compound() { let tokens = vec!( TupleStart(3), - TupleStart(0), - End, - - TupleStart(0), - End, + Null, + Null, TupleStart(2), Int(5), @@ -432,8 +428,7 @@ mod tests { SeqStart(1), StructStart("Inner", 3), Str("a"), - TupleStart(0), - End, + Null, Str("b"), Uint(5),