Does exceeding unwrapping affect a perfomance?

I needed a method like is_executable, so I went to crates.io and discovered a magic crate for that. However Windows implementation was questionable for my needs and I simplified it. However my implementation has too many unwraps:

metadata.is_dir() || (self.extension().is_some() &&
              (self.extension().unwrap() == "exe" || self.extension().unwrap() == "bat"))

Should I worry about that, or Rust compiler is smart enough and will eliminate the extra unwrapping? How would you implemented the code?

metadata.is_dir() || matches!(self.extension, Some("exe") | Some("bat"))
7 Likes

Slight improvement:

metadata.is_dir() || matches!(self.extension(), Some("exe" | "bat"))
9 Likes

Nice, thank you guys.

Because it's actually an OsStr, you can't pattern match it. But you can still avoid most of the duplication with is_some_and.

metadata.is_dir() || self.extension().is_some_and(|s| s == "exe" || s == "bat")

And to answer the title: I tried some stuff in godbolt, and unwrap by itself got optimized away just fine. However, when extension is involved, it leaves 3 uninlined function calls and the unwraps come back. Unwraps are much faster than extension anyway, so extension should be your main concern.

1 Like

Thank you for the comprehensive analysis. I assume that the fastest solution will look like :

If self.name.len() < 5 -> no,
If self.name[len-4] != '.' -> no,
If self.name[len-1] != 'e' goto check-t,
If self.name[len-3] != 'e' -> no,
If self.name[len-2] != 'x' -> no,
-> yes,
check-t: If self.name[len-1] != 't' -> no,
If self.name[len-3] != 'b' -> no,
If self.name[len-2] != 'a' -> no,
-> yes.

And check-t can be done in a parallel branch. However, a readability of the code will be worse, and it stops me from using the approach.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.