mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 14:51:01 +00:00
Swap AnimalDeserializer with a state machine to be fairer
165ns vs 193ns, 374ns vs 342ns
This commit is contained in:
@@ -550,10 +550,10 @@ mod tests {
|
|||||||
|
|
||||||
#[deriving(Eq, Show)]
|
#[deriving(Eq, Show)]
|
||||||
enum IntsDeserializerState {
|
enum IntsDeserializerState {
|
||||||
StartState,
|
IntsDeserializserStartState,
|
||||||
SepOrEndState,
|
IntsDeserializserSepOrEndState,
|
||||||
ValueState,
|
IntsDeserializserValueState,
|
||||||
EndState,
|
IntsDeserializserEndState,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IntsDeserializer {
|
struct IntsDeserializer {
|
||||||
@@ -567,7 +567,7 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn new(values: Vec<int>) -> IntsDeserializer {
|
fn new(values: Vec<int>) -> IntsDeserializer {
|
||||||
IntsDeserializer {
|
IntsDeserializer {
|
||||||
state: StartState,
|
state: IntsDeserializserStartState,
|
||||||
len: values.len(),
|
len: values.len(),
|
||||||
iter: values.move_iter(),
|
iter: values.move_iter(),
|
||||||
value: None,
|
value: None,
|
||||||
@@ -579,31 +579,31 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Result<Token, Error>> {
|
fn next(&mut self) -> Option<Result<Token, Error>> {
|
||||||
match self.state {
|
match self.state {
|
||||||
StartState => {
|
IntsDeserializserStartState => {
|
||||||
self.state = SepOrEndState;
|
self.state = IntsDeserializserSepOrEndState;
|
||||||
Some(Ok(SeqStart(self.len)))
|
Some(Ok(SeqStart(self.len)))
|
||||||
}
|
}
|
||||||
SepOrEndState => {
|
IntsDeserializserSepOrEndState => {
|
||||||
match self.iter.next() {
|
match self.iter.next() {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
self.state = ValueState;
|
self.state = IntsDeserializserValueState;
|
||||||
self.value = Some(value);
|
self.value = Some(value);
|
||||||
Some(Ok(Sep))
|
Some(Ok(Sep))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.state = EndState;
|
self.state = IntsDeserializserEndState;
|
||||||
Some(Ok(End))
|
Some(Ok(End))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ValueState => {
|
IntsDeserializserValueState => {
|
||||||
self.state = SepOrEndState;
|
self.state = IntsDeserializserSepOrEndState;
|
||||||
match self.value.take() {
|
match self.value.take() {
|
||||||
Some(value) => Some(Ok(Int(value))),
|
Some(value) => Some(Ok(Int(value))),
|
||||||
None => Some(Err(self.end_of_stream_error())),
|
None => Some(Err(self.end_of_stream_error())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndState => {
|
IntsDeserializserEndState => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -623,9 +623,9 @@ mod tests {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn expect_num<T: NumCast>(&mut self) -> Result<T, Error> {
|
fn expect_num<T: NumCast>(&mut self) -> Result<T, Error> {
|
||||||
assert_eq!(self.state, ValueState);
|
assert_eq!(self.state, IntsDeserializserValueState);
|
||||||
|
|
||||||
self.state = SepOrEndState;
|
self.state = IntsDeserializserSepOrEndState;
|
||||||
|
|
||||||
match self.value.take() {
|
match self.value.take() {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
@@ -741,11 +741,11 @@ mod tests {
|
|||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
enum AnimalDecoderState {
|
enum AnimalDecoderState {
|
||||||
AnimalState(Animal),
|
AnimalDecoderAnimalState(Animal),
|
||||||
DogState,
|
AnimalDecoderDogState,
|
||||||
FrogState,
|
AnimalDecoderFrogState,
|
||||||
IntState(int),
|
AnimalDecoderIntState(int),
|
||||||
StrState(StrBuf),
|
AnimalDecoderStrState(StrBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnimalDecoder {
|
struct AnimalDecoder {
|
||||||
@@ -757,7 +757,7 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn new(animal: Animal) -> AnimalDecoder {
|
fn new(animal: Animal) -> AnimalDecoder {
|
||||||
AnimalDecoder {
|
AnimalDecoder {
|
||||||
stack: vec!(AnimalState(animal)),
|
stack: vec!(AnimalDecoderAnimalState(animal)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -773,7 +773,7 @@ mod tests {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn read_int(&mut self) -> Result<int, Error> {
|
fn read_int(&mut self) -> Result<int, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(IntState(x)) => Ok(x),
|
Some(AnimalDecoderIntState(x)) => Ok(x),
|
||||||
_ => Err(SyntaxError),
|
_ => Err(SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -787,7 +787,7 @@ mod tests {
|
|||||||
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
fn read_char(&mut self) -> Result<char, Error> { Err(SyntaxError) }
|
||||||
fn read_str(&mut self) -> Result<StrBuf, Error> {
|
fn read_str(&mut self) -> Result<StrBuf, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(StrState(x)) => Ok(x),
|
Some(AnimalDecoderStrState(x)) => Ok(x),
|
||||||
_ => Err(SyntaxError),
|
_ => Err(SyntaxError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -795,8 +795,8 @@ mod tests {
|
|||||||
// Compound types:
|
// Compound types:
|
||||||
fn read_enum<T>(&mut self, name: &str, f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
fn read_enum<T>(&mut self, name: &str, f: |&mut AnimalDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
match self.stack.pop() {
|
match self.stack.pop() {
|
||||||
Some(AnimalState(animal)) => {
|
Some(AnimalDecoderAnimalState(animal)) => {
|
||||||
self.stack.push(AnimalState(animal));
|
self.stack.push(AnimalDecoderAnimalState(animal));
|
||||||
if name == "Animal" {
|
if name == "Animal" {
|
||||||
f(self)
|
f(self)
|
||||||
} else {
|
} else {
|
||||||
@@ -809,10 +809,10 @@ mod tests {
|
|||||||
|
|
||||||
fn read_enum_variant<T>(&mut self, names: &[&str], f: |&mut AnimalDecoder, uint| -> Result<T, Error>) -> Result<T, Error> {
|
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() {
|
let name = match self.stack.pop() {
|
||||||
Some(AnimalState(Dog)) => "Dog",
|
Some(AnimalDecoderAnimalState(Dog)) => "Dog",
|
||||||
Some(AnimalState(Frog(x0, x1))) => {
|
Some(AnimalDecoderAnimalState(Frog(x0, x1))) => {
|
||||||
self.stack.push(IntState(x1));
|
self.stack.push(AnimalDecoderIntState(x1));
|
||||||
self.stack.push(StrState(x0));
|
self.stack.push(AnimalDecoderStrState(x0));
|
||||||
"Frog"
|
"Frog"
|
||||||
}
|
}
|
||||||
_ => { return Err(SyntaxError); }
|
_ => { return Err(SyntaxError); }
|
||||||
@@ -877,34 +877,25 @@ mod tests {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
enum AnimalDeserializerState {
|
||||||
|
AnimalDeserializerAnimalState(Animal),
|
||||||
|
AnimalDeserializerDogState,
|
||||||
|
AnimalDeserializerFrogState,
|
||||||
|
AnimalDeserializerIntState(int),
|
||||||
|
AnimalDeserializerStrState(StrBuf),
|
||||||
|
AnimalDeserializerEndState,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct AnimalDeserializer {
|
struct AnimalDeserializer {
|
||||||
tokens: Vec<Token>,
|
stack: Vec<AnimalDeserializerState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimalDeserializer {
|
impl AnimalDeserializer {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new(animal: Animal) -> AnimalDeserializer {
|
fn new(animal: Animal) -> AnimalDeserializer {
|
||||||
let tokens = match animal {
|
|
||||||
Dog => {
|
|
||||||
vec!(
|
|
||||||
End,
|
|
||||||
EnumVariant("Dog"),
|
|
||||||
EnumStart("Animal"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Frog(x0, x1) => {
|
|
||||||
vec!(
|
|
||||||
End,
|
|
||||||
Int(x1),
|
|
||||||
StrBuf(x0),
|
|
||||||
EnumVariant("Frog"),
|
|
||||||
EnumStart("Animal"),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
AnimalDeserializer {
|
AnimalDeserializer {
|
||||||
tokens: tokens,
|
stack: vec!(AnimalDeserializerAnimalState(animal)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -912,10 +903,35 @@ mod tests {
|
|||||||
impl Iterator<Result<Token, Error>> for AnimalDeserializer {
|
impl Iterator<Result<Token, Error>> for AnimalDeserializer {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<Result<Token, Error>> {
|
fn next(&mut self) -> Option<Result<Token, Error>> {
|
||||||
match self.tokens.pop() {
|
match self.stack.pop() {
|
||||||
Some(token) => Some(Ok(token)),
|
Some(AnimalDeserializerAnimalState(Dog)) => {
|
||||||
|
self.stack.push(AnimalDeserializerEndState);
|
||||||
|
self.stack.push(AnimalDeserializerDogState);
|
||||||
|
Some(Ok(EnumStart("Animal")))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerAnimalState(Frog(x0, x1))) => {
|
||||||
|
self.stack.push(AnimalDeserializerEndState);
|
||||||
|
self.stack.push(AnimalDeserializerIntState(x1));
|
||||||
|
self.stack.push(AnimalDeserializerStrState(x0));
|
||||||
|
self.stack.push(AnimalDeserializerFrogState);
|
||||||
|
Some(Ok(EnumStart("Animal")))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerDogState) => {
|
||||||
|
Some(Ok(EnumVariant("Dog")))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerFrogState) => {
|
||||||
|
Some(Ok(EnumVariant("Frog")))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerIntState(x)) => {
|
||||||
|
Some(Ok(Int(x)))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerStrState(x)) => {
|
||||||
|
Some(Ok(StrBuf(x)))
|
||||||
|
}
|
||||||
|
Some(AnimalDeserializerEndState) => {
|
||||||
|
Some(Ok(End))
|
||||||
|
}
|
||||||
None => None,
|
None => None,
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user