mirror of
https://github.com/microsoft/GSL.git
synced 2025-04-01 08:56:29 -04:00
improve performance of span_iterator w/ clang
Issue: #1165 Before this PR, the range-for loop was ~3300x slower. After this PR, it is ~1.005x slower The clang optimizer is very good at optimizing `current != end`, so we changed to this idiom. This moves the Expects assertion into the constructor instead of on the hot-path which is called whenever either operator++ or operator* is called. Note: The codegen for the assertion is still a missed optimization, but less worrisome as it only happens once per iterator. Note: benchmarks on M1 Macbook Pro w/ Apple Clang 16.0.0
This commit is contained in:
parent
87f9d76886
commit
898db79600
@ -140,7 +140,10 @@ namespace details
|
||||
|
||||
constexpr span_iterator(pointer begin, pointer end, pointer current)
|
||||
: begin_(begin), end_(end), current_(current)
|
||||
{}
|
||||
{
|
||||
Expects(begin && current && end);
|
||||
Expects(begin <= current && current <= end);
|
||||
}
|
||||
|
||||
constexpr operator span_iterator<const Type>() const noexcept
|
||||
{
|
||||
@ -149,21 +152,18 @@ namespace details
|
||||
|
||||
constexpr reference operator*() const noexcept
|
||||
{
|
||||
Expects(begin_ && end_);
|
||||
Expects(begin_ <= current_ && current_ < end_);
|
||||
Expects(current_ != end_);
|
||||
return *current_;
|
||||
}
|
||||
|
||||
constexpr pointer operator->() const noexcept
|
||||
{
|
||||
Expects(begin_ && end_);
|
||||
Expects(begin_ <= current_ && current_ < end_);
|
||||
Expects(current_ != end_);
|
||||
return current_;
|
||||
}
|
||||
constexpr span_iterator& operator++() noexcept
|
||||
{
|
||||
Expects(begin_ && current_ && end_);
|
||||
Expects(current_ < end_);
|
||||
Expects(current_ != end_);
|
||||
// clang-format off
|
||||
GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
|
||||
// clang-format on
|
||||
@ -180,8 +180,7 @@ namespace details
|
||||
|
||||
constexpr span_iterator& operator--() noexcept
|
||||
{
|
||||
Expects(begin_ && end_);
|
||||
Expects(begin_ < current_);
|
||||
Expects(begin != current_);
|
||||
--current_;
|
||||
return *this;
|
||||
}
|
||||
@ -195,7 +194,6 @@ namespace details
|
||||
|
||||
constexpr span_iterator& operator+=(const difference_type n) noexcept
|
||||
{
|
||||
if (n != 0) Expects(begin_ && current_ && end_);
|
||||
if (n > 0) Expects(end_ - current_ >= n);
|
||||
if (n < 0) Expects(current_ - begin_ >= -n);
|
||||
// clang-format off
|
||||
@ -220,7 +218,6 @@ namespace details
|
||||
|
||||
constexpr span_iterator& operator-=(const difference_type n) noexcept
|
||||
{
|
||||
if (n != 0) Expects(begin_ && current_ && end_);
|
||||
if (n > 0) Expects(current_ - begin_ >= n);
|
||||
if (n < 0) Expects(end_ - current_ >= -n);
|
||||
GSL_SUPPRESS(bounds .1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user