Skip to content

Commit

Permalink
improve performance of span_iterator w/ clang (microsoft#1166)
Browse files Browse the repository at this point in the history
* improve performance of span_iterator w/ clang

Issue: microsoft#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
  • Loading branch information
carsonRadtke authored Nov 12, 2024
1 parent 87f9d76 commit f8ec309
Showing 1 changed file with 7 additions and 9 deletions.
16 changes: 7 additions & 9 deletions include/gsl/span
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ namespace details

constexpr span_iterator(pointer begin, pointer end, pointer current)
: begin_(begin), end_(end), current_(current)
{}
{
Expects(begin_ <= current_ && current <= end_);
}

constexpr operator span_iterator<const Type>() const noexcept
{
Expand All @@ -149,21 +151,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
Expand All @@ -180,8 +179,7 @@ namespace details

constexpr span_iterator& operator--() noexcept
{
Expects(begin_ && end_);
Expects(begin_ < current_);
Expects(begin_ != current_);
--current_;
return *this;
}
Expand Down

0 comments on commit f8ec309

Please sign in to comment.