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)
This commit is contained in:
Erick Tryzelaar
2014-06-14 10:48:01 -07:00
parent 8e657078ef
commit f46d5a9973
2 changed files with 351 additions and 361 deletions
+346 -351
View File
@@ -71,8 +71,8 @@ fn main() {
let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()}; let to_encode_object = TestStruct{data_str:"example of string to encode".to_string()};
let mut m = io::MemWriter::new(); let mut m = io::MemWriter::new();
{ {
let mut encoder = json::Encoder::new(&mut m as &mut Writer); let mut serializer = json::Serializer::new(&mut m as &mut Writer);
match to_encode_object.encode(&mut encoder) { match to_encode_object.encode(&mut serializer) {
Ok(()) => (), Ok(()) => (),
Err(e) => fail!("json encoding error: {}", e) 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 ```rust
use serialize::json; use serialize::json;
let to_encode_object = "example of string to encode".to_string(); 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. 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() { fn main() {
let to_encode_object = TestStruct1 let to_encode_object = TestStruct1
{data_int: 1, data_str:"toto".to_string(), data_vector:vec![2,3,4,5]}; {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` // To deserialize use the `json::from_str` and `json::Decoder`
@@ -262,15 +262,15 @@ pub type Object = TreeMap<String, Json>;
impl Json { impl Json {
/// Encodes a json value into an io::writer. Uses a single line. /// Encodes a json value into an io::writer. Uses a single line.
pub fn to_writer(&self, wr: &mut Writer) -> EncodeResult { pub fn to_writer(&self, wr: &mut Writer) -> EncodeResult {
let mut encoder = Encoder::new(wr); let mut serializer = Serializer::new(wr);
self.serialize(&mut encoder) self.serialize(&mut serializer)
} }
/// Encodes a json value into an io::writer. /// Encodes a json value into an io::writer.
/// Pretty-prints in a more readable format. /// Pretty-prints in a more readable format.
pub fn to_pretty_writer(&self, wr: &mut Writer) -> EncodeResult { pub fn to_pretty_writer(&self, wr: &mut Writer) -> EncodeResult {
let mut encoder = PrettyEncoder::new(wr); let mut serializer = PrettySerializer::new(wr);
self.serialize(&mut encoder) self.serialize(&mut serializer)
} }
/// Encodes a json value into a string /// Encodes a json value into a string
@@ -748,7 +748,7 @@ fn spaces(n: uint) -> String {
} }
#[deriving(Show)] #[deriving(Show)]
enum EncoderState { enum SerializerState {
ValueState, ValueState,
SeqState(bool), SeqState(bool),
MapState(bool), MapState(bool),
@@ -756,16 +756,16 @@ enum EncoderState {
} }
/// A structure for implementing serialization to JSON. /// A structure for implementing serialization to JSON.
pub struct Encoder<'a> { pub struct Serializer<'a> {
wr: &'a mut Writer, wr: &'a mut Writer,
state_stack: Vec<EncoderState>, state_stack: Vec<SerializerState>,
} }
impl<'a> Encoder<'a> { impl<'a> Serializer<'a> {
/// Creates a new JSON encoder whose output will be written to the writer /// Creates a new JSON serializer whose output will be written to the writer
/// specified. /// specified.
pub fn new(wr: &'a mut Writer) -> Encoder<'a> { pub fn new(wr: &'a mut Writer) -> Serializer<'a> {
Encoder { Serializer {
wr: wr, wr: wr,
state_stack: vec!(ValueState), state_stack: vec!(ValueState),
} }
@@ -774,12 +774,12 @@ impl<'a> Encoder<'a> {
/// Encode the specified struct into a json [u8] /// Encode the specified struct into a json [u8]
pub fn buf_encode< pub fn buf_encode<
'a, 'a,
T: ser::Serializable<io::IoError, Encoder<'a>> T: ser::Serializable<io::IoError, Serializer<'a>>
>(value: &T) -> Vec<u8> { >(value: &T) -> Vec<u8> {
let mut wr = MemWriter::new(); let mut wr = MemWriter::new();
{ {
let mut encoder = Encoder::new(&mut wr); let mut serializer = Serializer::new(&mut wr);
value.serialize(&mut encoder).unwrap(); value.serialize(&mut serializer).unwrap();
} }
wr.unwrap() wr.unwrap()
} }
@@ -787,9 +787,9 @@ impl<'a> Encoder<'a> {
/// Encode the specified struct into a json str /// Encode the specified struct into a json str
pub fn str_encode< pub fn str_encode<
'a, 'a,
T: ser::Serializable<io::IoError, Encoder<'a>> T: ser::Serializable<io::IoError, Serializer<'a>>
>(value: &T) -> Result<String, Vec<u8>> { >(value: &T) -> Result<String, Vec<u8>> {
let buf = Encoder::buf_encode(value); let buf = Serializer::buf_encode(value);
String::from_utf8(buf) String::from_utf8(buf)
} }
@@ -887,7 +887,7 @@ impl<'a> Encoder<'a> {
} }
} }
impl<'a> ser::Serializer<io::IoError> for Encoder<'a> { impl<'a> ser::Serializer<io::IoError> for Serializer<'a> {
fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> { fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> {
match self.state_stack.pop() { match self.state_stack.pop() {
Some(ValueState) => self.serialize_value(token), Some(ValueState) => self.serialize_value(token),
@@ -899,18 +899,18 @@ impl<'a> ser::Serializer<io::IoError> 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 /// compact data
pub struct PrettyEncoder<'a> { pub struct PrettySerializer<'a> {
wr: &'a mut Writer, wr: &'a mut Writer,
indent: uint, indent: uint,
state_stack: Vec<EncoderState>, state_stack: Vec<SerializerState>,
} }
impl<'a> PrettyEncoder<'a> { impl<'a> PrettySerializer<'a> {
/// Creates a new encoder whose output will be written to the specified writer /// Creates a new serializer whose output will be written to the specified writer
pub fn new(wr: &'a mut Writer) -> PrettyEncoder<'a> { pub fn new(wr: &'a mut Writer) -> PrettySerializer<'a> {
PrettyEncoder { PrettySerializer {
wr: wr, wr: wr,
indent: 0, indent: 0,
state_stack: vec!(ValueState), state_stack: vec!(ValueState),
@@ -920,12 +920,12 @@ impl<'a> PrettyEncoder<'a> {
/// Encode the specified struct into a json [u8] /// Encode the specified struct into a json [u8]
pub fn buf_encode< pub fn buf_encode<
'a, 'a,
T: ser::Serializable<io::IoError, PrettyEncoder<'a>> T: ser::Serializable<io::IoError, PrettySerializer<'a>>
>(value: &T) -> Vec<u8> { >(value: &T) -> Vec<u8> {
let mut wr = MemWriter::new(); let mut wr = MemWriter::new();
{ {
let mut encoder = PrettyEncoder::new(&mut wr); let mut serializer = PrettySerializer::new(&mut wr);
value.serialize(&mut encoder).unwrap(); value.serialize(&mut serializer).unwrap();
} }
wr.unwrap() wr.unwrap()
} }
@@ -933,9 +933,9 @@ impl<'a> PrettyEncoder<'a> {
/// Encode the specified struct into a json str /// Encode the specified struct into a json str
pub fn str_encode< pub fn str_encode<
'a, 'a,
T: ser::Serializable<io::IoError, PrettyEncoder<'a>> T: ser::Serializable<io::IoError, PrettySerializer<'a>>
>(value: &T) -> Result<String, Vec<u8>> { >(value: &T) -> Result<String, Vec<u8>> {
let buf = PrettyEncoder::buf_encode(value); let buf = PrettySerializer::buf_encode(value);
String::from_utf8(buf) String::from_utf8(buf)
} }
@@ -1065,7 +1065,7 @@ impl<'a> PrettyEncoder<'a> {
} }
} }
impl<'a> ser::Serializer<io::IoError> for PrettyEncoder<'a> { impl<'a> ser::Serializer<io::IoError> for PrettySerializer<'a> {
fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> { fn serialize<'a>(&mut self, token: ser::Token<'a>) -> Result<(), io::IoError> {
match self.state_stack.pop() { match self.state_stack.pop() {
Some(ValueState) => self.serialize_value(token), Some(ValueState) => self.serialize_value(token),
@@ -1763,101 +1763,6 @@ impl<T: Iterator<char>> de::Deserializer<ParserError> for Parser<T> {
} }
} }
/*
/// A Builder consumes a json::Parser to create a generic Json structure.
pub struct Builder<T> {
parser: Parser<T>,
token: Option<JsonEvent>,
}
impl<T: Iterator<char>> Builder<T> {
/// Create a JSON Builder.
pub fn new(src: T) -> Builder<T> {
Builder {
parser: Parser::new(src),
token: None,
}
}
// Decode a Json value from a Parser.
pub fn build(&mut self) -> Result<Json, BuilderError> {
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<Json, BuilderError> {
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<Json, BuilderError> {
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<Json, BuilderError> {
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<Char>`. /// Decodes a json value from an `Iterator<Char>`.
pub fn from_iter< pub fn from_iter<
Iter: Iterator<char>, Iter: Iterator<char>,
@@ -2101,12 +2006,12 @@ impl fmt::Show for Json {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
extern crate test; use std::io;
use self::test::Bencher; use std::fmt::Show;
use std::str;
use std::collections::TreeMap;
use serialize::Encodable; use super::{Serializer, PrettySerializer};
use super::{Encoder, PrettyEncoder};
use super::{Json, Null, Boolean, Number, String, List, Object}; use super::{Json, Null, Boolean, Number, String, List, Object};
use super::{Parser, ParserError, from_iter, from_str}; use super::{Parser, ParserError, from_iter, from_str};
use super::{JsonDeserializer, from_json, ToJson}; use super::{JsonDeserializer, from_json, ToJson};
@@ -2126,11 +2031,6 @@ mod tests {
use ser::Serializable; use ser::Serializable;
use ser; use ser;
use std::io;
use std::fmt::Show;
use std::str;
use std::collections::TreeMap;
macro_rules! treemap { macro_rules! treemap {
($($k:expr => $v:expr),*) => ({ ($($k:expr => $v:expr),*) => ({
let mut _m = ::std::collections::TreeMap::new(); let mut _m = ::std::collections::TreeMap::new();
@@ -2139,7 +2039,7 @@ mod tests {
}) })
} }
#[deriving(PartialEq, Show, Encodable, Decodable)] #[deriving(PartialEq, Show)]
enum Animal { enum Animal {
Dog, Dog,
Frog(String, int) Frog(String, int)
@@ -2205,7 +2105,7 @@ mod tests {
} }
} }
#[deriving(PartialEq, Show, Encodable, Decodable)] #[deriving(PartialEq, Show)]
struct Inner { struct Inner {
a: (), a: (),
b: uint, b: uint,
@@ -2292,7 +2192,7 @@ mod tests {
} }
} }
#[deriving(PartialEq, Show, Encodable, Decodable)] #[deriving(PartialEq, Show)]
struct Outer { struct Outer {
inner: Vec<Inner>, inner: Vec<Inner>,
} }
@@ -2361,30 +2261,30 @@ mod tests {
fn test_encode_ok< fn test_encode_ok<
'a, 'a,
T: PartialEq + Show + ToJson + ser::Serializable<io::IoError, Encoder<'a>> T: PartialEq + Show + ToJson + ser::Serializable<io::IoError, Serializer<'a>>
>(errors: &[(T, &str)]) { >(errors: &[(T, &str)]) {
for &(ref value, out) in errors.iter() { for &(ref value, out) in errors.iter() {
let out = out.to_string(); let out = out.to_string();
let s = Encoder::str_encode(value).unwrap(); let s = Serializer::str_encode(value).unwrap();
assert_eq!(s, out); 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); assert_eq!(s, out);
} }
} }
fn test_pretty_encode_ok< fn test_pretty_encode_ok<
'a, 'a,
T: PartialEq + Show + ToJson + ser::Serializable<io::IoError, PrettyEncoder<'a>> T: PartialEq + Show + ToJson + ser::Serializable<io::IoError, PrettySerializer<'a>>
>(errors: &[(T, &str)]) { >(errors: &[(T, &str)]) {
for &(ref value, out) in errors.iter() { for &(ref value, out) in errors.iter() {
let out = out.to_string(); let out = out.to_string();
let s = PrettyEncoder::str_encode(value).unwrap(); let s = PrettySerializer::str_encode(value).unwrap();
assert_eq!(s, out); 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); assert_eq!(s, out);
} }
} }
@@ -2440,8 +2340,23 @@ mod tests {
test_pretty_encode_ok([ test_pretty_encode_ok([
(vec!(), "[]"), (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![ let long_test_list = List(vec![
@@ -2461,14 +2376,16 @@ mod tests {
test_pretty_encode_ok([ test_pretty_encode_ok([
( (
long_test_list, long_test_list,
"[\n \ concat!(
false,\n \ "[\n",
null,\n \ " false,\n",
[\n \ " null,\n",
\"foo\\nbar\",\n \ " [\n",
3.5\n \ " \"foo\\nbar\",\n",
]\n\ " 3.5\n",
]" " ]\n",
"]"
)
) )
]); ]);
} }
@@ -2488,13 +2405,26 @@ mod tests {
test_pretty_encode_ok([ test_pretty_encode_ok([
(treemap!(), "{}"), (treemap!(), "{}"),
(treemap!("a".to_string() => true), "{\n \"a\": true\n}"), (
treemap!("a".to_string() => true),
concat!(
"{\n",
" \"a\": true\n",
"}"
),
),
( (
treemap!( treemap!(
"a".to_string() => true, "a".to_string() => true,
"b".to_string() => false "b".to_string() => false
), ),
"{\n \"a\": true,\n \"b\": false\n}"), concat!(
"{\n",
" \"a\": true,\n",
" \"b\": false\n",
"}"
),
),
]); ]);
let complex_obj = Object(treemap!( let complex_obj = Object(treemap!(
@@ -2519,16 +2449,18 @@ mod tests {
test_pretty_encode_ok([ test_pretty_encode_ok([
( (
complex_obj.clone(), complex_obj.clone(),
"{\n \ concat!(
\"b\": [\n \ "{\n",
{\n \ " \"b\": [\n",
\"c\": \"\\f\\r\"\n \ " {\n",
},\n \ " \"c\": \"\\f\\r\"\n",
{\n \ " },\n",
\"d\": \"\"\n \ " {\n",
}\n \ " \"d\": \"\"\n",
]\n\ " }\n",
}" " ]\n",
"}"
),
) )
]); ]);
} }
@@ -2541,10 +2473,25 @@ mod tests {
]); ]);
test_pretty_encode_ok([ test_pretty_encode_ok([
(Dog, "{\n \"Dog\": []\n}"), (
Dog,
concat!(
"{\n",
" \"Dog\": []\n",
"}"
),
),
( (
Frog("Henry".to_string(), 349), 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([ test_pretty_encode_ok([
(None, "null"), (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); hm.insert(1, true);
let mut mem_buf = MemWriter::new(); let mut mem_buf = MemWriter::new();
{ {
let mut encoder = Encoder::new(&mut mem_buf as &mut Writer); let mut serializer = Serializer::new(&mut mem_buf as &mut Writer);
hm.serialize(&mut encoder).unwrap(); hm.serialize(&mut serializer).unwrap();
} }
let bytes = mem_buf.unwrap(); let bytes = mem_buf.unwrap();
let json_str = from_utf8(bytes.as_slice()).unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap();
@@ -3118,8 +3073,8 @@ mod tests {
hm.insert(1, true); hm.insert(1, true);
let mut mem_buf = MemWriter::new(); let mut mem_buf = MemWriter::new();
{ {
let mut encoder = PrettyEncoder::new(&mut mem_buf as &mut Writer); let mut serializer = PrettySerializer::new(&mut mem_buf as &mut Writer);
hm.serialize(&mut encoder).unwrap() hm.serialize(&mut serializer).unwrap()
} }
let bytes = mem_buf.unwrap(); let bytes = mem_buf.unwrap();
let json_str = from_utf8(bytes.as_slice()).unwrap(); let json_str = from_utf8(bytes.as_slice()).unwrap();
@@ -3422,132 +3377,154 @@ mod tests {
assert!(stack.get(1) == Key("foo")); assert!(stack.get(1) == Key("foo"));
} }
*/ */
}
fn small_json() -> String { #[cfg(test)]
r#"{ mod bench {
"a": 1.0, use std::collections::TreeMap;
"b": [ use serialize;
true, use test::Bencher;
"foo\nbar",
{ "c": {"d": null} } use super::{Json, Null, Boolean, Number, String, List, Object};
] use super::{Parser, from_str};
}"#.to_string() use de;
macro_rules! treemap {
($($k:expr => $v:expr),*) => ({
let mut _m = ::std::collections::TreeMap::new();
$(_m.insert($k, $v);)*
_m
})
} }
#[bench] fn json_str(count: uint) -> String {
fn bench_decoder_streaming_small(b: &mut Bencher) { let mut src = "[".to_string();
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();
for _ in range(0, count) { for _ in range(0, count) {
src.push_str(r#"{ "a": true, "b": null, "c":3.1415, "d": "Hello world", "e": src.push_str(r#"{"a":true,"b":null,"c":3.1415,"d":"Hello world","e":[1,2,3]},"#);
[1,2,3]},"#);
} }
src.push_str("{}]"); src.push_str("{}]");
return src; src
} }
#[bench] fn pretty_json_str(count: uint) -> String {
fn bench_decoder_streaming_large(b: &mut Bencher) { 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; use serialize::json;
let count = 500; let mut list = vec!();
let src = big_json(count); 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( || { b.iter( || {
let mut parser = json::Parser::new(src.as_slice().chars()); let mut parser = json::Parser::new(src.as_slice().chars());
@@ -3583,40 +3560,8 @@ mod tests {
}); });
} }
#[bench] fn bench_deserializer_streaming(b: &mut Bencher, count: uint) {
fn bench_decoder_large(b: &mut Bencher) { let src = json_str(count);
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);
b.iter( || { b.iter( || {
let mut parser = Parser::new(src.as_slice().chars()); 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(), Some(Ok(de::End)));
assert_eq!(parser.next(), None); assert_eq!(parser.next(), None);
loop { loop {
match parser.next() { match parser.next() {
None => return, None => return,
@@ -3663,30 +3607,81 @@ mod tests {
} }
#[bench] #[bench]
fn bench_deserializer_large(b: &mut Bencher) { fn bench_encoder_001(b: &mut Bencher) {
let count = 500; bench_encoder(b, 1)
let src = big_json(count); }
let mut list = vec!(); #[bench]
for _ in range(0, count) { fn bench_encoder_500(b: &mut Bencher) {
list.push(Object(treemap!( bench_encoder(b, 500)
"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);
b.iter( || { #[bench]
let json: Json = from_str(src.as_slice()).unwrap(); fn bench_encoder_001_pretty(b: &mut Bencher) {
assert_eq!(json, list); 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)
} }
} }
+5 -10
View File
@@ -208,7 +208,7 @@ mod tests {
use serialize::Decoder; 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::{TupleStart, StructStart, EnumStart};
use super::{SeqStart, MapStart, End}; use super::{SeqStart, MapStart, End};
use super::{Serializer, Serializable}; use super::{Serializer, Serializable};
@@ -341,8 +341,7 @@ mod tests {
#[test] #[test]
fn test_tokens_null() { fn test_tokens_null() {
let tokens = vec!( let tokens = vec!(
TupleStart(0), Null,
End,
); );
let mut serializer = AssertSerializer::new(tokens.move_iter()); let mut serializer = AssertSerializer::new(tokens.move_iter());
@@ -391,11 +390,8 @@ mod tests {
fn test_tokens_tuple_compound() { fn test_tokens_tuple_compound() {
let tokens = vec!( let tokens = vec!(
TupleStart(3), TupleStart(3),
TupleStart(0), Null,
End, Null,
TupleStart(0),
End,
TupleStart(2), TupleStart(2),
Int(5), Int(5),
@@ -432,8 +428,7 @@ mod tests {
SeqStart(1), SeqStart(1),
StructStart("Inner", 3), StructStart("Inner", 3),
Str("a"), Str("a"),
TupleStart(0), Null,
End,
Str("b"), Str("b"),
Uint(5), Uint(5),