Simplify the struct deserializer state machine

2515ns vs 3058ns
This commit is contained in:
Erick Tryzelaar 2014-05-26 07:46:17 -07:00
parent ada088eb85
commit 4b8c62828e

View File

@ -269,6 +269,7 @@ mod decoder {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
mod deserializer { mod deserializer {
use collections::HashMap;
use super::{Outer, Inner, Error, EndOfStream, SyntaxError}; use super::{Outer, Inner, Error, EndOfStream, SyntaxError};
use de::Deserializer; use de::Deserializer;
use de::{Token, Uint, Char, String, Null, TupleStart, StructStart, StructField, SeqStart, MapStart, End, Option}; use de::{Token, Uint, Char, String, Null, TupleStart, StructStart, StructField, SeqStart, MapStart, End, Option};
@ -283,8 +284,8 @@ mod deserializer {
StringState(String), StringState(String),
OptionState(bool), OptionState(bool),
TupleState(uint), TupleState(uint),
VecState(uint), VecState(Vec<Inner>),
MapState(uint), MapState(HashMap<String, Option<char>>),
EndState, EndState,
} }
@ -305,52 +306,16 @@ mod deserializer {
impl Iterator<Result<Token, Error>> for OuterDeserializer { impl Iterator<Result<Token, Error>> for OuterDeserializer {
#[inline] #[inline]
fn next(&mut self) -> Option<Result<Token, Error>> { fn next(&mut self) -> Option<Result<Token, Error>> {
match self.stack.last() { match self.stack.pop() {
Some(&OuterState(_)) => { Some(OuterState(Outer { inner })) => {
let inner = match self.stack.pop() {
Some(OuterState(Outer { inner })) => inner,
_ => { return Some(Err(self.syntax_error())); }
};
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(VecState(inner));
self.stack.push(EndState);
let len = inner.len();
for v in inner.move_iter().rev() {
self.stack.push(InnerState(v));
}
self.stack.push(VecState(len));
self.stack.push(FieldState("inner")); self.stack.push(FieldState("inner"));
Some(Ok(StructStart("Outer"))) Some(Ok(StructStart("Outer")))
} }
Some(&InnerState(_)) => { Some(InnerState(Inner { a: (), b, c })) => {
let ((), b, c) = match self.stack.pop() {
Some(InnerState(Inner { a, b, c })) => (a, b, c),
_ => { return Some(Err(self.syntax_error())); }
};
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(MapState(c));
self.stack.push(EndState);
let len = c.len();
for (k, v) in c.move_iter() {
self.stack.push(EndState);
match v {
Some(c) => {
self.stack.push(CharState(c));
self.stack.push(OptionState(true));
}
None => {
self.stack.push(OptionState(false));
}
}
self.stack.push(StringState(k));
self.stack.push(TupleState(2));
}
self.stack.push(MapState(len));
self.stack.push(FieldState("c")); self.stack.push(FieldState("c"));
self.stack.push(UintState(b)); self.stack.push(UintState(b));
@ -360,65 +325,42 @@ mod deserializer {
self.stack.push(FieldState("a")); self.stack.push(FieldState("a"));
Some(Ok(StructStart("Inner"))) Some(Ok(StructStart("Inner")))
} }
Some(&FieldState(_)) => { Some(FieldState(name)) => Some(Ok(StructField(name))),
match self.stack.pop() { Some(VecState(value)) => {
Some(FieldState(name)) => Some(Ok(StructField(name))), self.stack.push(EndState);
_ => Some(Err(self.syntax_error())), let len = value.len();
for inner in value.move_iter().rev() {
self.stack.push(InnerState(inner));
} }
Some(Ok(SeqStart(len)))
} }
Some(&VecState(_)) => { Some(MapState(value)) => {
match self.stack.pop() { self.stack.push(EndState);
Some(VecState(len)) => Some(Ok(SeqStart(len))), let len = value.len();
_ => Some(Err(self.syntax_error())), for (key, value) in value.move_iter() {
self.stack.push(EndState);
match value {
Some(c) => {
self.stack.push(CharState(c));
self.stack.push(OptionState(true));
}
None => {
self.stack.push(OptionState(false));
}
}
self.stack.push(StringState(key));
self.stack.push(TupleState(2));
} }
Some(Ok(MapStart(len)))
} }
Some(&MapState(_)) => { Some(TupleState(len)) => Some(Ok(TupleStart(len))),
match self.stack.pop() { Some(NullState) => Some(Ok(Null)),
Some(MapState(len)) => Some(Ok(MapStart(len))), Some(UintState(x)) => Some(Ok(Uint(x))),
_ => Some(Err(self.syntax_error())), Some(CharState(x)) => Some(Ok(Char(x))),
} Some(StringState(x)) => Some(Ok(String(x))),
} Some(OptionState(x)) => Some(Ok(Option(x))),
Some(&TupleState(_)) => { Some(EndState) => {
match self.stack.pop() { Some(Ok(End))
Some(TupleState(len)) => Some(Ok(TupleStart(len))),
_ => Some(Err(self.syntax_error())),
}
}
Some(&NullState) => {
match self.stack.pop() {
Some(NullState) => Some(Ok(Null)),
_ => Some(Err(self.syntax_error())),
}
}
Some(&UintState(_)) => {
match self.stack.pop() {
Some(UintState(x)) => Some(Ok(Uint(x))),
_ => Some(Err(self.syntax_error())),
}
}
Some(&CharState(_)) => {
match self.stack.pop() {
Some(CharState(x)) => Some(Ok(Char(x))),
_ => Some(Err(self.syntax_error())),
}
}
Some(&StringState(_)) => {
match self.stack.pop() {
Some(StringState(x)) => Some(Ok(String(x))),
_ => Some(Err(self.syntax_error())),
}
}
Some(&OptionState(_)) => {
match self.stack.pop() {
Some(OptionState(x)) => Some(Ok(Option(x))),
_ => Some(Err(self.syntax_error())),
}
}
Some(&EndState) => {
match self.stack.pop() {
Some(EndState) => Some(Ok(End)),
_ => Some(Err(self.syntax_error())),
}
} }
None => None, None => None,
} }
@ -456,17 +398,22 @@ fn bench_struct_decoder_outer_empty(b: &mut Bencher) {
} }
#[bench] #[bench]
fn bench_struct_deserializer_outer_empty(b: &mut Bencher) { fn bench_struct_decoder_inner_empty(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut map = HashMap::new(); let map = HashMap::new();
map.insert("abc".to_strbuf(), Some('c'));
let outer = Outer { let outer = Outer {
inner: vec!(), inner: vec!(
Inner {
a: (),
b: 5,
c: map,
},
)
}; };
let mut d = deserializer::OuterDeserializer::new(outer.clone()); let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Deserializable::deserialize(&mut d).unwrap(); let value: Outer = Decodable::decode(&mut d).unwrap();
assert_eq!(value, outer); assert_eq!(value, outer);
}) })
@ -495,6 +442,45 @@ fn bench_struct_decoder(b: &mut Bencher) {
}) })
} }
#[bench]
fn bench_struct_deserializer_outer_empty(b: &mut Bencher) {
b.iter(|| {
let mut map = HashMap::new();
map.insert("abc".to_strbuf(), Some('c'));
let outer = Outer {
inner: vec!(),
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserializable::deserialize(&mut d).unwrap();
assert_eq!(value, outer);
})
}
#[bench]
fn bench_struct_deserializer_inner_empty(b: &mut Bencher) {
b.iter(|| {
let map = HashMap::new();
let outer = Outer {
inner: vec!(
Inner {
a: (),
b: 5,
c: map,
},
)
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserializable::deserialize(&mut d).unwrap();
assert_eq!(value, outer);
})
}
#[bench] #[bench]
fn bench_struct_deserializer(b: &mut Bencher) { fn bench_struct_deserializer(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
@ -517,47 +503,3 @@ fn bench_struct_deserializer(b: &mut Bencher) {
assert_eq!(value, outer); assert_eq!(value, outer);
}) })
} }
#[bench]
fn bench_struct_decoder_inner_empty(b: &mut Bencher) {
b.iter(|| {
let mut map = HashMap::new();
let outer = Outer {
inner: vec!(
Inner {
a: (),
b: 5,
c: map,
},
)
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
assert_eq!(value, outer);
})
}
#[bench]
fn bench_struct_deserializerinner_empty(b: &mut Bencher) {
b.iter(|| {
let mut map = HashMap::new();
let outer = Outer {
inner: vec!(
Inner {
a: (),
b: 5,
c: map,
},
)
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserializable::deserialize(&mut d).unwrap();
assert_eq!(value, outer);
})
}