Skip to content

Add gsl::span vs std::span performance benchmark CI (fixes #1167)#1252

Open
Gafoor2005 wants to merge 17 commits into
microsoft:mainfrom
Gafoor2005:main
Open

Add gsl::span vs std::span performance benchmark CI (fixes #1167)#1252
Gafoor2005 wants to merge 17 commits into
microsoft:mainfrom
Gafoor2005:main

Conversation

@Gafoor2005

Copy link
Copy Markdown

Summary

Adds a continuous benchmark suite that tracks performance parity between
gsl::span and std::span on every PR, across all supported compilers
and platforms.

Closes #1167.


What this adds

  • benchmark/span_bench.cpp — benchmarks from @galenelias comparing
    gsl::span and std::span across five workloads (is_sorted, ranges,
    custom iterator loop, min_element algorithm, range-for min)
  • benchmark/CMakeLists.txt — self-contained build; fetches
    google-benchmark v1.9.0 and googletest via FetchContent; links against
    the local repo's GSL (not a pinned tag) so every PR tests its own
    changes
  • benchmark/check_regression.py — parses benchmark JSON output, pairs
    StdSpan/GslSpan variants by name, computes gsl_ns / std_ns ratio,
    writes a Markdown table, exits 1 on regression
  • .github/workflows/span_benchmark.yml — runs on every PR across 13
    configs (GCC 13/14, Clang 17/18, MSVC 2022, clang-cl, Apple Clang ×
    C++20/23); posts or updates a single PR comment with results from all
    configs

Approach

The comparison is in-run ratio (gsl_ns / std_ns) rather than
comparing against a stored baseline. Both span variants run in the same
process on the same machine at the same moment, so GitHub-hosted runner
noise (~10–15%) cancels out. A ratio above 1.15 (15% slower than
std::span) fails CI.

This sidesteps the "Status: Blocked" concern about noisy shared runners —
no self-hosted runner or external service needed.

Each benchmark runs 10 repetitions; the script uses the mean and
reports stddev so reviewers can see measurement stability.


CI matrix

OS Compiler Standard
ubuntu-latest GCC 13 C++20
ubuntu-latest GCC 14 C++20, C++23
ubuntu-latest Clang 17 C++20
ubuntu-latest Clang 18 C++20, C++23
windows-latest MSVC 2022 C++20, C++23
windows-latest clang-cl C++20, C++23
macos-14 Apple Clang C++20, C++23

Example PR comment

The workflow posts (and updates) a single comment per PR that looks like:

GCC-14-cpp20

Benchmark std mean gsl mean ratio status
IsSorted 124 ns 125 ns 1.01× ✅ 1.01×
IsSortedRanges 88 ns 89 ns 1.01× ✅ 1.01×
MinElementAlgorithm 95 ns 96 ns 1.01× ✅ 1.01×

Notes

  • -fbounds-safety config is stubbed out in the matrix with a comment
    explaining it's not yet stable in mainline Clang releases — easy to
    uncomment when it lands
  • FetchContent deps are cached on CMakeLists.txt hash so CI doesn't
    re-clone on every run
  • The comment job uses peter-evans/find-comment +
    create-or-update-comment so repeated pushes to the same PR update
    the existing comment rather than flooding the thread

Gafoor2005 added 14 commits May 19, 2026 12:41
Add benchmark suite comparing gsl::span vs std::span performance across
is_sorted and min_element operations. Includes GitHub Actions workflow
for automated testing on GCC 14, Clang 18, and MSVC with results uploaded
as artifacts for performance regression analysis.
Ensure both text and JSON benchmark outputs are properly populated
in workflow artifacts by running benchmarks separately instead of
using pipe redirection, which was leaving the text file empty.
Test PR for PR-based benchmark
@Gafoor2005

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@carsonRadtke carsonRadtke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for getting this put together! It'll be great to have the infrastructure necessary to compare GSL types to standard library types. I have briefly reviewed many of the changes, please address my comments and I will perform a more in-depth review once comments have been resolved. I will also assign Copilot as a reviewer, so you get some more feedback; please address those comments too.

This currently is a proof-of-concept of a really cool feature that will help us develop GSL, but I want to make sure the PR is clean and well-understood before running any workflows and merging your changes.

Also, using AI as a tool to write code is great. Please make sure you understand the code that you are contributing. I want to hold all contributions to a high standard and right now this PR needs some work.

Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread benchmark/README.md Outdated
Comment thread benchmark/CMakeLists.txt Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a CI-run benchmark suite to continuously track performance parity between gsl::span and std::span, generating a per-PR Markdown report and failing CI when gsl::span exceeds a configured slowdown threshold.

Changes:

  • Adds a Google Benchmark-based executable comparing gsl::span vs std::span across several workloads.
  • Adds a Python regression checker that parses benchmark JSON, computes gsl/std ratios, and emits a PR-comment-ready Markdown report.
  • Adds a GitHub Actions workflow that runs the benchmark across a multi-OS/compiler/standard matrix, uploads results, and posts/updates a single PR comment.
Show a summary per file
File Description
benchmark/span_bench.cpp Adds the benchmark program comparing gsl::span and std::span workloads.
benchmark/README.md Documents purpose, local usage, CI matrix, and how regression detection works.
benchmark/CMakeLists.txt Self-contained CMake build that fetches benchmark dependencies and builds against the local GSL checkout.
benchmark/check_regression.py Parses JSON results, pairs Std/GSL benchmarks, computes ratios, and generates Markdown + CI status.
.github/workflows/span_benchmark.yml CI matrix runner that builds/runs benchmarks, aggregates artifacts, and posts/updates a PR comment.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 10

Comment thread benchmark/span_bench.cpp Outdated
Comment thread benchmark/check_regression.py
Comment thread benchmark/CMakeLists.txt Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
…rkflow

- Updated span_benchmark.yml to streamline job configurations and improve artifact handling.
- Introduced span_benchmark_comment.yml to automate PR comment updates with benchmark results.
- Enhanced CMakeLists.txt to support benchmark builds with new GSL_BENCHMARK option.
- Removed README.md from benchmark directory and adjusted check_regression.py for cleaner report generation.
- Modified span_bench.cpp to include necessary headers for benchmarking.
@Gafoor2005 Gafoor2005 requested a review from Copilot June 8, 2026 12:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment thread .github/workflows/span_benchmark.yml Outdated
Comment on lines +57 to +58
# Strip the trailing _mean / _stddev to get the canonical name
base_name = name[: name.rfind(f"_{agg}")]
Comment thread CMakeLists.txt Outdated
Comment thread CMakeLists.txt
Comment thread benchmark/span_bench.cpp
Comment on lines +12 to +15
constexpr size_t vec_size = 1000;
v.reserve(vec_size);
for (int i = 0; i < vec_size; ++i)
v.push_back(i);
Comment thread benchmark/span_bench.cpp
for (auto _ : state)
{
std::span<const int> sp = vec;
benchmark::DoNotOptimize(std::min_element(sp.begin(), sp.end()));
@Gafoor2005 Gafoor2005 requested a review from carsonRadtke June 8, 2026 13:41
@Gafoor2005

Copy link
Copy Markdown
Author

I have addressed all your changes and most of the Copilot's too, there are few unresolved Copilot changes which I don't know are that reasonable. I need your opinion on them

@carsonRadtke

Copy link
Copy Markdown
Member

I see the updates. I have been out of office the past week and will continue to be out next week. I'll review the changes when I get back the week of the 22nd. Thanks for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add performance tests to PR actions

3 participants