use std::fmt::Show; use std::collections::HashMap; use test::Bencher; use serialize::{Decoder, Decodable}; use de::{Deserializer, Deserializable}; ////////////////////////////////////////////////////////////////////////////// #[deriving(Show)] enum Error { EndOfStream, SyntaxError, OtherError(String), } ////////////////////////////////////////////////////////////////////////////// mod decoder { use std::collections::HashMap; use std::collections::hashmap::MoveEntries; use serialize; use super::{Error, EndOfStream, SyntaxError, OtherError}; enum Value { StringValue(String), IntValue(int), } pub struct IntDecoder { len: uint, iter: MoveEntries, stack: Vec, } impl IntDecoder { #[inline] pub fn new(values: HashMap) -> IntDecoder { IntDecoder { len: values.len(), iter: values.move_iter(), stack: vec!(), } } } impl serialize::Decoder for IntDecoder { fn error(&mut self, msg: &str) -> Error { OtherError(msg.to_string()) } // Primitive types: fn read_nil(&mut self) -> Result<(), Error> { Err(SyntaxError) } fn read_uint(&mut self) -> Result { Err(SyntaxError) } fn read_u64(&mut self) -> Result { Err(SyntaxError) } fn read_u32(&mut self) -> Result { Err(SyntaxError) } fn read_u16(&mut self) -> Result { Err(SyntaxError) } fn read_u8(&mut self) -> Result { Err(SyntaxError) } #[inline] fn read_int(&mut self) -> Result { match self.stack.pop() { Some(IntValue(x)) => Ok(x), Some(_) => Err(SyntaxError), None => Err(EndOfStream), } } fn read_i64(&mut self) -> Result { Err(SyntaxError) } fn read_i32(&mut self) -> Result { Err(SyntaxError) } fn read_i16(&mut self) -> Result { Err(SyntaxError) } fn read_i8(&mut self) -> Result { Err(SyntaxError) } fn read_bool(&mut self) -> Result { Err(SyntaxError) } fn read_f64(&mut self) -> Result { Err(SyntaxError) } fn read_f32(&mut self) -> Result { Err(SyntaxError) } fn read_char(&mut self) -> Result { Err(SyntaxError) } #[inline] fn read_str(&mut self) -> Result { match self.stack.pop() { Some(StringValue(x)) => Ok(x), Some(_) => Err(SyntaxError), None => Err(EndOfStream), } } // Compound types: fn read_enum(&mut self, _name: &str, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_enum_variant(&mut self, _names: &[&str], _f: |&mut IntDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_enum_variant_arg(&mut self, _a_idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_enum_struct_variant(&mut self, _names: &[&str], _f: |&mut IntDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_enum_struct_variant_field(&mut self, _f_name: &str, _f_idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_struct(&mut self, _s_name: &str, _len: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_struct_field(&mut self, _f_name: &str, _f_idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_tuple(&mut self, _f: |&mut IntDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_arg(&mut self, _a_idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_struct(&mut self, _s_name: &str, _f: |&mut IntDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_tuple_struct_arg(&mut self, _a_idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } // Specialized types: fn read_option(&mut self, _f: |&mut IntDecoder, bool| -> Result) -> Result { Err(SyntaxError) } fn read_seq(&mut self, _f: |&mut IntDecoder, uint| -> Result) -> Result { Err(SyntaxError) } fn read_seq_elt(&mut self, _idx: uint, _f: |&mut IntDecoder| -> Result) -> Result { Err(SyntaxError) } #[inline] fn read_map(&mut self, f: |&mut IntDecoder, uint| -> Result) -> Result { let len = self.len; f(self, len) } #[inline] fn read_map_elt_key(&mut self, _idx: uint, f: |&mut IntDecoder| -> Result) -> Result { match self.iter.next() { Some((key, value)) => { self.stack.push(IntValue(value)); self.stack.push(StringValue(key)); f(self) } None => { Err(SyntaxError) } } } #[inline] fn read_map_elt_val(&mut self, _idx: uint, f: |&mut IntDecoder| -> Result) -> Result { f(self) } } } ////////////////////////////////////////////////////////////////////////////// mod deserializer { use std::collections::HashMap; use std::collections::hashmap::MoveEntries; use super::{Error, EndOfStream, SyntaxError}; use de; #[deriving(PartialEq, Show)] enum State { StartState, KeyOrEndState, ValueState(int), EndState, } pub struct IntDeserializer { stack: Vec, len: uint, iter: MoveEntries, } impl IntDeserializer { #[inline] pub fn new(values: HashMap) -> IntDeserializer { IntDeserializer { stack: vec!(StartState), len: values.len(), iter: values.move_iter(), } } } impl Iterator> for IntDeserializer { #[inline] fn next(&mut self) -> Option> { match self.stack.pop() { Some(StartState) => { self.stack.push(KeyOrEndState); Some(Ok(de::MapStart(self.len))) } Some(KeyOrEndState) => { match self.iter.next() { Some((key, value)) => { self.stack.push(ValueState(value)); Some(Ok(de::String(key))) } None => { self.stack.push(EndState); Some(Ok(de::End)) } } } Some(ValueState(x)) => { self.stack.push(KeyOrEndState); Some(Ok(de::Int(x))) } Some(EndState) => { None } None => { None } } } } impl de::Deserializer for IntDeserializer { #[inline] fn end_of_stream_error(&self) -> Result { Err(EndOfStream) } #[inline] fn syntax_error(&self) -> Result { Err(SyntaxError) } } } ////////////////////////////////////////////////////////////////////////////// fn run_decoder< E: Show, D: Decoder, T: Clone + PartialEq + Show + Decodable >(mut d: D, value: T) { let v: T = Decodable::decode(&mut d).unwrap(); assert_eq!(value, v); } #[bench] fn bench_decoder_000(b: &mut Bencher) { b.iter(|| { let m: HashMap = HashMap::new(); run_decoder(decoder::IntDecoder::new(m.clone()), m) }) } #[bench] fn bench_decoder_003(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); for i in range(0i, 3) { m.insert(i.to_string(), i); } run_decoder(decoder::IntDecoder::new(m.clone()), m) }) } #[bench] fn bench_decoder_100(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); for i in range(0i, 100) { m.insert(i.to_string(), i); } run_decoder(decoder::IntDecoder::new(m.clone()), m) }) } fn run_deserializer< E: Show, D: Deserializer, T: Clone + PartialEq + Show + Deserializable >(mut d: D, value: T) { let v: T = Deserializable::deserialize(&mut d).unwrap(); assert_eq!(value, v); } #[bench] fn bench_deserializer_000(b: &mut Bencher) { b.iter(|| { let m: HashMap = HashMap::new(); run_deserializer(deserializer::IntDeserializer::new(m.clone()), m) }) } #[bench] fn bench_deserializer_003(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); for i in range(0i, 3) { m.insert(i.to_string(), i); } run_deserializer(deserializer::IntDeserializer::new(m.clone()), m) }) } #[bench] fn bench_deserializer_100(b: &mut Bencher) { b.iter(|| { let mut m: HashMap = HashMap::new(); for i in range(0i, 100) { m.insert(i.to_string(), i); } run_deserializer(deserializer::IntDeserializer::new(m.clone()), m) }) }