On the Rust-lang users forum I've found out that the compiler will actually optimize this kind of code, so that processing time is not wasted:
fn process(data: SomeDataType) -> Result<(), Error> {
// a lot of processing and/or allocations here
data.something()?;
// a lot of processing and/or allocations here
Ok(())
}
However, it happens only when the compiler
can tell that your other work has no side-effects, but there are going to be many cases where it is unable to make the reordering because it can't tell that it doesn't have side-effects, or maybe the code does something that you don't consider to be a side-effect, but which the compiler does count. (e.g. increment, then decrement a ref-count)
So wouldn't it be better to check the result at it first appearance instead of checking for side-effects and reordering if the ?
is used?
For example, the code I've listed above would be compiled to something like this:
fn process(data: SomeDataType) -> Result<(), Error> {
if (data.something().is_err()) {
return Err(data.something().err().unwrap())
}
// a lot of processing and/or allocations here
data.something()?;
// a lot of processing and/or allocations here
Ok(())
}
And to something like this when the data is not available at the beginning of the function:
fn process() -> Result<bool, Error> {
// a lot of processing and/or allocations here
let something: Result<SomeDataType, Error> = get_some_data_type();
// a lot of processing and/or allocations here
something?.get_something();
Ok(())
}
fn process() -> Result<bool, Error> {
// a lot of processing and/or allocations here
let something: Result<SomeDataType, Error> = get_some_data_type();
if (something.is_err()) {
return Err(something.err().unwrap())
}
// a lot of processing and/or allocations here
something?.get_something();
Ok(())
}
This can help to have code optimized and free of boilerplate code at the same time.
Example of such code:
fn process(data: SomeDataType) -> Result<(), Error> {
let something = data.something()?;
let something1 = data.something1()?;
let something2 = data.something2()?;
// a lot of processing and/or allocations here
something;
// a lot of processing and/or allocations here
something1;
// a lot of processing and/or allocations here
something2;
// a lot of processing and/or allocations here
Ok(())
}
Link to the original post on users forum: