Skip to content

Add fast path to SpanHelpers.SequenceEqual using Unsafe.AreSame#123674

Closed
Copilot wants to merge 2 commits intomainfrom
copilot/add-fast-path-sequence-equal
Closed

Add fast path to SpanHelpers.SequenceEqual using Unsafe.AreSame#123674
Copilot wants to merge 2 commits intomainfrom
copilot/add-fast-path-sequence-equal

Conversation

Copy link
Contributor

Copilot AI commented Jan 27, 2026

Description

Adds early exit to SpanHelpers.SequenceEqual(ref byte first, ref byte second, nuint length) when first and second reference the same memory location.

Previously, the Unsafe.AreSame check was only performed for lengths ≥ sizeof(nuint). Now it's checked unconditionally at method entry, consistent with SpanHelpers.T.cs and SpanHelpers.Char.cs.

Changes

  • Add Unsafe.AreSame check at method start to return true immediately for same-reference comparisons
  • Remove redundant check from Longer: block (now unreachable for same-reference case)
  • Add micro-benchmarks for byte and char spans covering same-reference, same-content, and different-content scenarios

Benchmark for validation

Post this comment on the PR to trigger EgorBot:

@EgorBot -x64 -arm
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;

BenchmarkSwitcher.FromAssembly(typeof(Bench).Assembly).Run(args);

[MemoryDiagnoser]
public class Bench
{
    private byte[] _byteArray = default!;
    private byte[] _byteArrayCopy = default!;

    [Params(16, 256, 4096)]
    public int Length { get; set; }

    [GlobalSetup]
    public void Setup()
    {
        _byteArray = new byte[Length];
        _byteArrayCopy = new byte[Length];
        for (int i = 0; i < Length; i++)
        {
            _byteArray[i] = (byte)(i & 0xFF);
            _byteArrayCopy[i] = (byte)(i & 0xFF);
        }
    }

    [Benchmark]
    public bool Byte_SameReference()
    {
        ReadOnlySpan<byte> span = _byteArray;
        return span.SequenceEqual(span);
    }

    [Benchmark]
    public bool Byte_DiffRef_SameContent() => _byteArray.AsSpan().SequenceEqual(_byteArrayCopy);
}
Original prompt

Add a fast path to public static unsafe bool SequenceEqual(ref byte first, ref byte second, nuint length) to return true if first and second reference the same memory location (Unsafe.AreSame).

Once the PR is built, add micro-benchmarks to validate the performance impact of this change.

Use MemoryExtensions.SequenceEqual over spans as a performance target. Try different lengths and content scenarios (same references, different references but same content, completely different content) for char, byte (use separate TestData for benchmarks input so the jit doesn't fold them right away).


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@EgorBo
Copy link
Member

EgorBo commented Jan 27, 2026

(Mostly just testing the cooperation of copilot and EgorBot)

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.

2 participants