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

Document performance considerations of context vs with_context #318

Open
TheButlah opened this issue Dec 23, 2021 · 1 comment
Open

Document performance considerations of context vs with_context #318

TheButlah opened this issue Dec 23, 2021 · 1 comment

Comments

@TheButlah
Copy link

It would be good to document best practices for whether we should use context() or with_context(). Is it better to eagerly evaluate the error struct or lazily do it? Should I always just use with_context()?

I'm using this in a no_std environment so performance matters to me.

@shepmaster
Copy link
Owner

In general, there should be no inherent performance differences between context or with_context. Rust's optimizers pretty trivially improve the closure for with_context.

The important thing to remember is that, most of the time, you shouldn't have any function calls when using context:

// Good
foo.context(BarSnafu { name, id: 32, date: &date });

// Bad
foo.context(BarSnafu { name: name.to_string(), id: fetch_id_from_server(), date: Date::now() });

// Better
foo.with_context(|| BarSnafu { name: name.to_string(), id: fetch_id_from_server(), date: Date::now() });

The rationale is that those function calls will be evaluated regardless if foo is in an error state or not. When using with_context, the closure is only evaluated when foo is a Result::Err, so the function calls are made lazy again.

However, most of the time, you can use context because SNAFU will only apply the Into::into conversion on the context arguments when the value is an Err. Most of the time, this means you should transfer ownership of an existing value to the context selector or give it a reference (see name and date in the first example).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants