mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-19 09:58:08 -05:00
Improve performance of til::equals (#19653)
As explained in the added comment. Perf 📈.
This commit is contained in:
@@ -159,16 +159,29 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
// Just like std::wstring_view::operator==().
|
||||
//
|
||||
// At the time of writing wmemcmp() is not an intrinsic for MSVC,
|
||||
// but the STL uses it to implement wide string comparisons.
|
||||
// This produces 3x the assembly _per_ comparison and increases
|
||||
// runtime by 2-3x for strings of medium length (16 characters)
|
||||
// and 5x or more for long strings (128 characters or more).
|
||||
// NOTE: If you pass a literal, ALWAYS pass it as the 2nd argument.
|
||||
// This is because MSVC does not understand that `lhs.size() == rhs.size()` implies
|
||||
// that a constant size on one side implies a constant size on the other side.
|
||||
// As such the size argument to memcmp() must be the constant size, which is `rhs`.
|
||||
//
|
||||
// The STL uses wmemcmp() to implement wide string comparisons.
|
||||
// Compared to memcmp() this results 3x the assembly per comparison,
|
||||
// while running 2-3x slower for 16 chars and >5x slower for >128 chars.
|
||||
// See: https://github.com/microsoft/STL/issues/2289
|
||||
template<typename T, typename Traits>
|
||||
bool equals(const std::basic_string_view<T, Traits>& lhs, const std::basic_string_view<T, Traits>& rhs) noexcept
|
||||
constexpr bool equals(const std::basic_string_view<T, Traits>& lhs, const std::basic_string_view<T, Traits>& rhs) noexcept
|
||||
{
|
||||
return lhs.size() == rhs.size() && __builtin_memcmp(lhs.data(), rhs.data(), lhs.size() * sizeof(T)) == 0;
|
||||
return lhs.size() == rhs.size() && __builtin_memcmp(lhs.data(), rhs.data(), rhs.size() * sizeof(T)) == 0;
|
||||
}
|
||||
|
||||
constexpr bool equals(const std::string_view& lhs, const std::string_view& rhs) noexcept
|
||||
{
|
||||
return equals<>(lhs, rhs);
|
||||
}
|
||||
|
||||
constexpr bool equals(const std::wstring_view& lhs, const std::wstring_view& rhs) noexcept
|
||||
{
|
||||
return equals<>(lhs, rhs);
|
||||
}
|
||||
|
||||
// Just like _memicmp, but without annoying locales.
|
||||
|
||||
Reference in New Issue
Block a user