Skip to content

Commit

Permalink
Early evaluate line loc in NameAndLoc::operator==
Browse files Browse the repository at this point in the history
I do not know if checking the tracker name or the tracker's file
part of the location first would provide better results, but
in the common case, the line part of the location check should be
rather unique, because different `SECTION`s will have different
source lines where they are defined.

I also propagated this same check into `ITracker::findChild`,
because this significantly improves performance of section tracking
in Debug builds -> 10% in macro benchmark heavily focused on section
tracking. In Release build there is usually no difference, because
the inliner will inline `NameAndLoc::operator==` into `findChild`,
and then eliminate the redundant check. (If the inliner decides
against, then this still improves the performance on average).
  • Loading branch information
horenmar committed Feb 20, 2023
1 parent 4f7c8cb commit 584973a
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
7 changes: 6 additions & 1 deletion src/catch2/internal/catch_test_case_tracker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ namespace TestCaseTracking {
m_children.begin(),
m_children.end(),
[&nameAndLocation]( ITrackerPtr const& tracker ) {
return tracker->nameAndLocation() == nameAndLocation;
auto const& tnameAndLoc = tracker->nameAndLocation();
if ( tnameAndLoc.location.line !=
nameAndLocation.location.line ) {
return false;
}
return tnameAndLoc == nameAndLocation;
} );
return ( it != m_children.end() ) ? it->get() : nullptr;
}
Expand Down
13 changes: 11 additions & 2 deletions src/catch2/internal/catch_test_case_tracker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ namespace TestCaseTracking {

NameAndLocation( std::string&& _name, SourceLineInfo const& _location );
friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {
return lhs.name == rhs.name
&& lhs.location == rhs.location;
// This is a very cheap check that should have a very high hit rate.
// If we get to SourceLineInfo::operator==, we will redo it, but the
// cost of repeating is trivial at that point (we will be paying
// multiple strcmp/memcmps at that point).
if ( lhs.location.line != rhs.location.line ) { return false; }
return lhs.name == rhs.name && lhs.location == rhs.location;
}
friend bool operator!=(NameAndLocation const& lhs,
NameAndLocation const& rhs) {
Expand All @@ -50,6 +54,11 @@ namespace TestCaseTracking {

friend bool operator==( NameAndLocation const& lhs,
NameAndLocationRef const& rhs ) {
// This is a very cheap check that should have a very high hit rate.
// If we get to SourceLineInfo::operator==, we will redo it, but the
// cost of repeating is trivial at that point (we will be paying
// multiple strcmp/memcmps at that point).
if ( lhs.location.line != rhs.location.line ) { return false; }
return StringRef( lhs.name ) == rhs.name &&
lhs.location == rhs.location;
}
Expand Down

0 comments on commit 584973a

Please sign in to comment.