Skip to content

Commit 7f6e080

Browse files
committed
add fast path on Path::eq for exact equality
1 parent a083dd6 commit 7f6e080

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

library/std/src/path.rs

+20-1
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,25 @@ impl FusedIterator for Components<'_> {}
979979
impl<'a> cmp::PartialEq for Components<'a> {
980980
#[inline]
981981
fn eq(&self, other: &Components<'a>) -> bool {
982+
let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self;
983+
984+
// Fast path for exact matches, e.g. for hashmap lookups.
985+
// Don't explicitly compare the prefix or has_physical_root fields since they'll
986+
// either be covered by the `path` buffer or are only relevant for `prefix_verbatim()`.
987+
if self.path.len() == other.path.len()
988+
&& self.front == other.front
989+
&& self.back == State::Body
990+
&& other.back == State::Body
991+
&& self.prefix_verbatim() == other.prefix_verbatim()
992+
{
993+
// possible future improvement: this could bail out earlier if there were a
994+
// reverse memcmp/bcmp comparing back to front
995+
if self.path == other.path {
996+
return true;
997+
}
998+
}
999+
1000+
// compare back to front since absolute paths often share long prefixes
9821001
Iterator::eq(self.clone().rev(), other.clone().rev())
9831002
}
9841003
}
@@ -1013,7 +1032,7 @@ fn compare_components(mut left: Components<'_>, mut right: Components<'_>) -> cm
10131032
// The fast path isn't taken for paths with a PrefixComponent to avoid backtracking into
10141033
// the middle of one
10151034
if left.prefix.is_none() && right.prefix.is_none() && left.front == right.front {
1016-
// this might benefit from a [u8]::first_mismatch simd implementation, if it existed
1035+
// possible future improvement: a [u8]::first_mismatch simd implementation
10171036
let first_difference =
10181037
match left.path.iter().zip(right.path.iter()).position(|(&a, &b)| a != b) {
10191038
None if left.path.len() == right.path.len() => return cmp::Ordering::Equal,

0 commit comments

Comments
 (0)