serde/bench_enum.rs
Erick Tryzelaar d8fb2abd03 Change the json enum serialization to {"variant":["fields", ...]}
test bench_enum::bench_decoder_dog                   ... bench:       112 ns/iter (+/- 15)
test bench_enum::bench_decoder_frog                  ... bench:       336 ns/iter (+/- 6)
test bench_enum::bench_deserializer_dog              ... bench:       120 ns/iter (+/- 4)
test bench_enum::bench_deserializer_frog             ... bench:       317 ns/iter (+/- 15)
test bench_map::bench_decoder_000                    ... bench:       528 ns/iter (+/- 13)
test bench_map::bench_decoder_003                    ... bench:      2459 ns/iter (+/- 74)
test bench_map::bench_decoder_100                    ... bench:     70756 ns/iter (+/- 1979)
test bench_map::bench_deserializer_000               ... bench:       753 ns/iter (+/- 30)
test bench_map::bench_deserializer_003               ... bench:      2574 ns/iter (+/- 111)
test bench_map::bench_deserializer_100               ... bench:     62374 ns/iter (+/- 1714)
test bench_struct::bench_decoder_0_0                 ... bench:       609 ns/iter (+/- 14)
test bench_struct::bench_decoder_1_0                 ... bench:      1620 ns/iter (+/- 44)
test bench_struct::bench_decoder_1_5                 ... bench:      4393 ns/iter (+/- 88)
test bench_struct::bench_deserializer_0_0            ... bench:       699 ns/iter (+/- 10)
test bench_struct::bench_deserializer_1_0            ... bench:      2160 ns/iter (+/- 53)
test bench_struct::bench_deserializer_1_5            ... bench:      4987 ns/iter (+/- 87)
test bench_vec::bench_decoder_int_000                ... bench:        20 ns/iter (+/- 1)
test bench_vec::bench_decoder_int_003                ... bench:       148 ns/iter (+/- 3)
test bench_vec::bench_decoder_int_100                ... bench:      1009 ns/iter (+/- 44)
test bench_vec::bench_decoder_u8_000                 ... bench:        16 ns/iter (+/- 0)
test bench_vec::bench_decoder_u8_003                 ... bench:       152 ns/iter (+/- 12)
test bench_vec::bench_decoder_u8_100                 ... bench:      1457 ns/iter (+/- 95)
test bench_vec::bench_deserializer_int_000           ... bench:        16 ns/iter (+/- 0)
test bench_vec::bench_deserializer_int_003           ... bench:       153 ns/iter (+/- 9)
test bench_vec::bench_deserializer_int_100           ... bench:      1015 ns/iter (+/- 38)
test bench_vec::bench_deserializer_u8_000            ... bench:        16 ns/iter (+/- 1)
test bench_vec::bench_deserializer_u8_003            ... bench:       160 ns/iter (+/- 130)
test bench_vec::bench_deserializer_u8_100            ... bench:      1225 ns/iter (+/- 112)
test json::tests::bench_decoder_large                ... bench:   1979093 ns/iter (+/- 67769)
test json::tests::bench_decoder_small                ... bench:      4644 ns/iter (+/- 208)
test json::tests::bench_decoder_streaming_large      ... bench:    848383 ns/iter (+/- 96301)
test json::tests::bench_decoder_streaming_small      ... bench:      1834 ns/iter (+/- 120)
test json::tests::bench_deserializer_large           ... bench:   1882598 ns/iter (+/- 137262)
test json::tests::bench_deserializer_small           ... bench:      3945 ns/iter (+/- 161)
test json::tests::bench_deserializer_streaming_large ... bench:    990086 ns/iter (+/- 157794)
test json::tests::bench_deserializer_streaming_small ... bench:      2135 ns/iter (+/- 211)
2014-06-09 07:51:53 -07:00

310 lines
10 KiB
Rust

use test::Bencher;
use serialize::{Decoder, Decodable};
use de::{Deserializer, Deserializable, Token};
//////////////////////////////////////////////////////////////////////////////
#[deriving(Clone, PartialEq, Show, Decodable)]
enum Animal {
Dog,
Frog(String, int)
}
impl<E, D: Deserializer<E>> Deserializable<E, D> for Animal {
#[inline]
fn deserialize_token(d: &mut D, token: Token) -> Result<Animal, E> {
match try!(d.expect_enum_start(token, "Animal", ["Dog", "Frog"])) {
0 => {
try!(d.expect_enum_end());
Ok(Dog)
}
1 => {
let x0 = try!(Deserializable::deserialize(d));
let x1 = try!(Deserializable::deserialize(d));
try!(d.expect_enum_end());
Ok(Frog(x0, x1))
}
_ => d.syntax_error(),
}
}
}
//////////////////////////////////////////////////////////////////////////////
#[deriving(Show)]
enum Error {
EndOfStream,
SyntaxError,
}
//////////////////////////////////////////////////////////////////////////////
mod decoder {
use serialize::Decoder;
use super::{Animal, Dog, Frog, Error, SyntaxError};
enum State {
AnimalState(Animal),
DogState,
FrogState,
IntState(int),
StringState(String),
}
pub struct AnimalDecoder {
stack: Vec<State>,
}
impl AnimalDecoder {
#[inline]
pub fn new(animal: Animal) -> AnimalDecoder {
AnimalDecoder {
stack: vec!(AnimalState(animal)),
}
}
}
impl Decoder<Error> for AnimalDecoder {
// Primitive types:
fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) }
fn read_uint(&mut self) -> Result<uint, Error> { Err(SyntaxError) }
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
fn read_u8(&mut self) -> Result<u8, Error> { Err(SyntaxError) }
#[inline]
fn read_int(&mut self) -> Result<int, Error> {
match self.stack.pop() {
Some(IntState(x)) => Ok(x),
_ => Err(SyntaxError),
}
}
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
#[inline]
fn read_str(&mut self) -> Result<String, Error> {
match self.stack.pop() {
Some(StringState(x)) => Ok(x),
_ => Err(SyntaxError),
}
}
// Compound types:
#[inline]
fn read_enum<T>(&mut self, name: &str, f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> {
match self.stack.pop() {
Some(AnimalState(animal)) => {
self.stack.push(AnimalState(animal));
if name == "Animal" {
f(self)
} else {
Err(SyntaxError)
}
}
_ => Err(SyntaxError)
}
}
#[inline]
fn read_enum_variant<T>(&mut self, names: &[&str], f: |&mut AnimalDecoder, uint| -> Result<T, Error>) -> Result<T, Error> {
let name = match self.stack.pop() {
Some(AnimalState(Dog)) => "Dog",
Some(AnimalState(Frog(x0, x1))) => {
self.stack.push(IntState(x1));
self.stack.push(StringState(x0));
"Frog"
}
_ => { return Err(SyntaxError); }
};
let idx = match names.iter().position(|n| *n == name) {
Some(idx) => idx,
None => { return Err(SyntaxError); }
};
f(self, idx)
}
#[inline]
fn read_enum_variant_arg<T>(&mut self, _a_idx: uint, f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> {
f(self)
}
fn read_enum_struct_variant<T>(&mut self,
_names: &[&str],
_f: |&mut AnimalDecoder, uint| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
fn read_enum_struct_variant_field<T>(&mut self,
_f_name: &str,
_f_idx: uint,
_f: |&mut AnimalDecoder| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
fn read_struct<T>(&mut self, _s_name: &str, _len: uint, _f: |&mut AnimalDecoder| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
fn read_struct_field<T>(&mut self,
_f_name: &str,
_f_idx: uint,
_f: |&mut AnimalDecoder| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
fn read_tuple<T>(&mut self, _f: |&mut AnimalDecoder, uint| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
fn read_tuple_arg<T>(&mut self, _a_idx: uint, _f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
fn read_tuple_struct<T>(&mut self,
_s_name: &str,
_f: |&mut AnimalDecoder, uint| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
fn read_tuple_struct_arg<T>(&mut self,
_a_idx: uint,
_f: |&mut AnimalDecoder| -> Result<T, Error>)
-> Result<T, Error> { Err(SyntaxError) }
// Specialized types:
fn read_option<T>(&mut self, _f: |&mut AnimalDecoder, bool| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
#[inline]
fn read_seq<T>(&mut self, f: |&mut AnimalDecoder, uint| -> Result<T, Error>) -> Result<T, Error> {
f(self, 3)
}
#[inline]
fn read_seq_elt<T>(&mut self, _idx: uint, f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> {
f(self)
}
fn read_map<T>(&mut self, _f: |&mut AnimalDecoder, uint| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
fn read_map_elt_key<T>(&mut self, _idx: uint, _f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
fn read_map_elt_val<T>(&mut self, _idx: uint, _f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
}
}
//////////////////////////////////////////////////////////////////////////////
mod deserializer {
use super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError};
use de::Deserializer;
use de::{Token, Int, String, EnumStart, End};
enum State {
AnimalState(Animal),
IntState(int),
StringState(String),
EndState,
}
pub struct AnimalDeserializer {
stack: Vec<State>,
}
impl AnimalDeserializer {
#[inline]
pub fn new(animal: Animal) -> AnimalDeserializer {
AnimalDeserializer {
stack: vec!(AnimalState(animal)),
}
}
}
impl Iterator<Result<Token, Error>> for AnimalDeserializer {
#[inline]
fn next(&mut self) -> Option<Result<Token, Error>> {
match self.stack.pop() {
Some(AnimalState(Dog)) => {
self.stack.push(EndState);
Some(Ok(EnumStart("Animal", "Dog", 0)))
}
Some(AnimalState(Frog(x0, x1))) => {
self.stack.push(EndState);
self.stack.push(IntState(x1));
self.stack.push(StringState(x0));
Some(Ok(EnumStart("Animal", "Frog", 2)))
}
Some(IntState(x)) => {
Some(Ok(Int(x)))
}
Some(StringState(x)) => {
Some(Ok(String(x)))
}
Some(EndState) => {
Some(Ok(End))
}
None => None,
}
}
}
impl Deserializer<Error> for AnimalDeserializer {
#[inline]
fn end_of_stream_error<T>(&self) -> Result<T, Error> {
Err(EndOfStream)
}
#[inline]
fn syntax_error<T>(&self) -> Result<T, Error> {
Err(SyntaxError)
}
}
}
//////////////////////////////////////////////////////////////////////////////
#[bench]
fn bench_decoder_dog(b: &mut Bencher) {
b.iter(|| {
let animal = Dog;
let mut d = decoder::AnimalDecoder::new(animal.clone());
let value: Animal = Decodable::decode(&mut d).unwrap();
assert_eq!(value, animal);
})
}
#[bench]
fn bench_decoder_frog(b: &mut Bencher) {
b.iter(|| {
let animal = Frog("Henry".to_string(), 349);
let mut d = decoder::AnimalDecoder::new(animal.clone());
let value: Animal = Decodable::decode(&mut d).unwrap();
assert_eq!(value, animal);
})
}
#[bench]
fn bench_deserializer_dog(b: &mut Bencher) {
b.iter(|| {
let animal = Dog;
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
let value: Animal = Deserializable::deserialize(&mut d).unwrap();
assert_eq!(value, animal);
})
}
#[bench]
fn bench_deserializer_frog(b: &mut Bencher) {
b.iter(|| {
let animal = Frog("Henry".to_string(), 349);
let mut d = deserializer::AnimalDeserializer::new(animal.clone());
let value: Animal = Deserializable::deserialize(&mut d).unwrap();
assert_eq!(value, animal);
})
}