Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit recursion to 128 levels #163

Merged
merged 1 commit into from Dec 3, 2016
Merged

Limit recursion to 128 levels #163

merged 1 commit into from Dec 3, 2016

Conversation

dtolnay
Copy link
Member

@dtolnay dtolnay commented Oct 27, 2016

No description provided.

@dtolnay
Copy link
Member Author

dtolnay commented Oct 27, 2016

I tried a few ways of factoring this into a helper but they were all slower in benchmarks. 701d84e is ~3% slower. As is, this PR has no effect on benchmarks.

@oli-obk
Copy link
Member

oli-obk commented Oct 27, 2016

Did you try slapping inline-always on the function?

@dtolnay
Copy link
Member Author

dtolnay commented Oct 27, 2016

I tried #[inline(always)] on that helper, as well as #[inline(always)] with each of these three variations factored out of the helper:

#[cold]
#[inline(never)]
fn stack_overflow_error<T>(&mut self) -> Result<T> {
    Err(self.peek_error(ErrorCode::Custom("recursion limit exceeded".into())))
}
#[cold]
#[inline(never)]
fn stack_overflow_error(&mut self) -> Error {
    self.peek_error(ErrorCode::Custom("recursion limit exceeded".into()))
}
#[cold]
#[inline(never)]
fn stack_overflow_error() -> ErrorCode {
    ErrorCode::Custom("recursion limit exceeded".into())
}

Those range from 3% (the last one) to 10% (the middle one) slower than this PR.

10% is pretty astonishing given that we are talking about canada.json which is full of floating point numbers and parsing those is slow to begin with, so something weird is going on. I will check it out in perf when I have time.

@dtolnay
Copy link
Member Author

dtolnay commented Oct 27, 2016

I get pretty much the same slowdowns on my laptop Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz and my desktop Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz.

Copy link
Member

@erickt erickt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks great. I'd be happy landing this now if you want to think more on the builder design.

@@ -107,6 +108,7 @@ impl<R: Read> DeserializerImpl<R> {
DeserializerImpl {
read: read,
str_buf: Vec::with_capacity(128),
remaining_depth: 128,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about adding a Deserializer::with_recursion_limit method so this can be customized? Or maybe a Deserializer builder with a with_recursion_limit method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am keeping #162 open to decide whether this needs to be configurable.

@@ -205,12 +207,30 @@ impl<R: Read> DeserializerImpl<R> {
visitor.visit_str(s)
}
b'[' => {
self.remaining_depth -= 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose all this could be moved into the SeqVisitor but I'm not sure if that'd make things any more clean.

@@ -523,6 +543,10 @@ impl<R: Read> DeserializerImpl<R> {
}
}

fn stack_overflow() -> ErrorCode {
ErrorCode::Custom("recursion limit exceeded".into())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a shame we can't add error codes in a backwards compatible fashion. Next major release though :)

@dtolnay
Copy link
Member Author

dtolnay commented Dec 3, 2016

I still can't make a better factored version run as fast. I will give it another shot once we have likely/unlikely rust-lang/rust#26179.

@dtolnay dtolnay merged commit 3516a90 into master Dec 3, 2016
@dtolnay dtolnay deleted the limit branch December 3, 2016 19:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants