Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Audit MemoryExtensions.IndexOf variants #75754

Merged
merged 3 commits into from
Oct 26, 2022
Merged

Conversation

Rob-Hague
Copy link
Contributor

@Rob-Hague Rob-Hague commented Sep 16, 2022

Hi @adamsitnik, after your #73768 I am submitting a few changes which I noticed and presumed were not intentionally left out:

  1. Add the SpanHelpers.Char specialisation to LastIndexOf(Span, ROS) to match LastIndexOf(ROS, ROS). I did not forward the Span version to ROS version to be consistent with IndexOf(Span, ROS) and IndexOf(ROS, ROS), being wary of related discussion in Vectorize {Last}IndexOf{Any} and {Last}IndexOfAnyExcept without code duplication #73768 (comment)
  2. I did forward the LastIndexOfAny(Span, ROS) to LastIndexOfAny(ROS, ROS) to be consistent with IndexOfAny and considering the next changes:
  3. Add more byte cases to LastIndexOfAny and IndexOfAny to be consistent with the short path

Things I noticed but did not change, deciding they were intentional:

  1. Missing int- and long-size paths on a few variants. I saw a couple removed in that PR
  2. Varying use of IsBitwiseEquatable vs CanVectorizeAndBenefit. I saw some tweaks in the last commit of that PR
  3. SpanHelpers.IndexOfAnyValueType has up to 5-value versions but LastIndexOfAnyValueType has only up to 4-value

Sadly I am having a few troubles getting some benchmarks running. I will submit this as a draft until then, if you see anything I am doing obviously wrong I would appreciate the pointer (I am a rookie with the runtime repo).

edit: I was using the wrong corerun path. I changed
dotnet run -c Release -f net8.0 -- --coreRun C:\src\artifacts\bin\coreclr\windows.x64.Release\corerun.exe C:\src\runtime\artifacts\bin\coreclr\windows.x64.Release\corerun.exe

to

dotnet run -c Release -- --coreRun C:\src\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe C:\src\runtime\artifacts\bin\testhost\net7.0-windows-Release-x64\shared\Microsoft.NETCore.App\8.0.0\corerun.exe

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Sep 16, 2022
@dnfadmin
Copy link

dnfadmin commented Sep 16, 2022

CLA assistant check
All CLA requirements met.

@ghost
Copy link

ghost commented Sep 16, 2022

Tagging subscribers to this area: @dotnet/area-system-memory
See info in area-owners.md if you want to be subscribed.

Issue Details

Hi @adamsitnik, after your #73768 I am submitting a few changes which I noticed and presumed were not intentionally left out:

  1. Add the SpanHelpers.Char specialisation to LastIndexOf(Span, ROS) to match LastIndexOf(ROS, ROS). I did not forward the Span version to ROS version to be consistent with IndexOf(Span, ROS) and IndexOf(ROS, ROS), being wary of related discussion in Vectorize {Last}IndexOf{Any} and {Last}IndexOfAnyExcept without code duplication #73768 (comment)
  2. I did forward the LastIndexOfAny(Span, ROS) to LastIndexOfAny(ROS, ROS) to be consistent with IndexOfAny and considering the next changes:
  3. Add more byte cases to LastIndexOfAny and IndexOfAny to be consistent with the short path

Things I noticed but did not change, deciding they were intentional:

  1. Missing int- and long-size paths on a few variants. I saw a couple removed in that PR
  2. Varying use of IsBitwiseEquatable vs CanVectorizeAndBenefit. I saw some tweaks in the last commit of that PR
  3. SpanHelpers.IndexOfAnyValueType has up to 5-value versions but LastIndexOfAnyValueType has only up to 4-value

Sadly I am having a few troubles getting some benchmarks running. I will submit this as a draft until then, if you see anything I am doing obviously wrong I would appreciate the pointer (I am a rookie with the runtime repo).

I built main branch and copied the artifacts folder out to C:\src\artifacts\ then switched to my branch and built that (to C:\src\runtime\artifacts\). I am running from within my benchmark project dotnet build then
dotnet run -c Release -f net8.0 -- --coreRun C:\src\artifacts\bin\coreclr\windows.x64.Release\corerun.exe C:\src\runtime\artifacts\bin\coreclr\windows.x64.Release\corerun.exe
but I am getting output like below.

// **************************
// Benchmark: PrValidation.LastIndexOf_char_Span: Job-NLFAIL(Toolchain=\artifacts\bin\coreclr\windows.x64.Release\corerun.exe) [SearchSpaceCount=1024, SearchSpaceValue=1, ValueSpaceCount=1]
// *** Execute ***
// Launch: 1 / 1
// Execute: C:\src\artifacts\bin\coreclr\1a9e0e35-fd39-459c-800a-15f99cad96fc\corerun.exe 50419f21-5ca4-43db-985b-56f1f7210afd.dll --benchmarkName "System.Memory.PrValidation.LastIndexOf_char_Span(SearchSpaceCount: 1024, SearchSpaceValue: 1, ValueSpaceCount: 1)" --job Toolchain=\artifacts\bin\coreclr\windows.x64.Release\corerun.exe --benchmarkId 0 in C:\src\bench\bin\Release\net8.0\win-x64\50419f21-5ca4-43db-985b-56f1f7210afd\bin\Release\net8.0\publish
ExitCode != 0 and no results reported
No Workload Results were obtained from the run.
// Benchmark Process 19124 has exited with code -532462766.
dotnet --info

.NET SDK:
 Version:   8.0.100-alpha.1.22465.14
 Commit:    c09cc8aada

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22000
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\8.0.100-alpha.1.22465.14\

Host:
  Version:      8.0.0-alpha.1.22462.15
  Architecture: x64
  Commit:       c804303ace

.NET SDKs installed:
  6.0.400 [C:\Program Files\dotnet\sdk]
  8.0.100-alpha.1.22465.14 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.0-alpha.1.22463.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.0-alpha.1.22462.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 6.0.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 8.0.0-alpha.1.22457.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found:
  x86   [C:\Program Files (x86)\dotnet]

Environment variables:
  Not set

global.json file:
  Not found

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

benchmark src

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
	<RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
  </ItemGroup>

</Project>
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Runtime.CompilerServices;
using System.Linq;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Jobs;

namespace System.Memory
{
    public class PrValidation
    {
        //[Params(4, 64, 1024)]
        [Params(1024)]
        public int SearchSpaceCount;

        //[Params(0, 1)]
        [Params(1)]
        public int SearchSpaceValue;

        //[Params(0, 1, 2, 3, 4, 5)]
        [Params(1)]
        public int ValueSpaceCount;

        private byte[] _searchSpaceBytes, _valueSpaceBytes;
        private char[] _searchSpaceChars, _valueSpaceChars;

        [GlobalSetup]
        public void Setup()
        {
            _searchSpaceBytes = Enumerable.Repeat((byte)SearchSpaceValue, SearchSpaceCount).ToArray();
            _searchSpaceChars = Enumerable.Repeat((char)SearchSpaceValue, SearchSpaceCount).ToArray();

            _valueSpaceBytes = Enumerable.Range(1, ValueSpaceCount).Select(Convert.ToByte).ToArray();
            _valueSpaceChars = Enumerable.Range(1, ValueSpaceCount).Select(Convert.ToChar).ToArray();
        }

        [Benchmark] public void LastIndexOf_char_Span() => new Span<char>(_searchSpaceChars).LastIndexOf(_valueSpaceChars);

        // [Benchmark] public void IndexOfAny_byte_Span() => new Span<byte>(_searchSpaceBytes).IndexOfAny(_valueSpaceBytes);
        // [Benchmark] public void IndexOfAny_byte_ROS() => new ReadOnlySpan<byte>(_searchSpaceBytes).IndexOfAny(_valueSpaceBytes);

        // [Benchmark] public void LastIndexOfAny_byte_Span() => new Span<byte>(_searchSpaceBytes).LastIndexOfAny(_valueSpaceBytes);
        // [Benchmark] public void LastIndexOfAny_byte_ROS() => new ReadOnlySpan<byte>(_searchSpaceBytes).LastIndexOfAny(_valueSpaceBytes);
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
        }
    }
}

Author: rob-hague
Assignees: -
Labels:

area-System.Memory, community-contribution

Milestone: -

public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>?
{
if (Unsafe.SizeOf<T>() == sizeof(byte) && RuntimeHelpers.IsBitwiseEquatable<T>())
return SpanHelpers.LastIndexOfAny(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was calling the same function as the fallback

@Rob-Hague
Copy link
Contributor Author

Rob-Hague commented Sep 17, 2022

Benchmarks summary:

Regressions in IndexOfAny_byte_ROS and LastIndexOfAny_byte_ROS for 2-value
Regressions in LastIndexOfAny_byte_Span and LastIndexOfAny_char_Span for 5-value

I guess the former is related to codegen.
I guess LastIndexOfAny_byte_Span 5-value suffers from extra indirection to call the same method (there is no vectorized 5-value LastIndexOfAny).
My guess for LastIndexOfAny_char_Span 5-value is that this comes from benchmarking an unrepresentative search-space (and the probabilistic map suffers heavily from this)

I will try a more representative search space soon. In the meantime if you have any thoughts on what changes you would take (if any) please let me know. Thanks

BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22000.978/21H2)
AMD Ryzen 7 5700U with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.100-alpha.1.22465.14
  [Host]     : .NET 8.0.0 (8.0.22.46215), X64 RyuJIT AVX2
  main : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  PR : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2

Method Job SearchSpaceCount ValueSpaceCount Mean Error StdDev Median Ratio RatioSD
IndexOfAny_byte_ROS main 8 1 9.830 ns 0.2249 ns 0.6156 ns 10.041 ns 1.00 0.00
IndexOfAny_byte_ROS PR 8 1 4.971 ns 0.1001 ns 0.0937 ns 4.979 ns 0.55 0.04
IndexOfAny_byte_ROS main 8 2 6.129 ns 0.1493 ns 0.2576 ns 5.950 ns 1.00 0.00
IndexOfAny_byte_ROS PR 8 2 8.934 ns 0.2029 ns 0.3957 ns 8.968 ns 1.46 0.09
IndexOfAny_byte_ROS main 8 3 9.384 ns 0.2156 ns 0.4154 ns 9.364 ns 1.00 0.00
IndexOfAny_byte_ROS PR 8 3 9.654 ns 0.2196 ns 0.5387 ns 9.661 ns 1.03 0.08
IndexOfAny_byte_ROS main 8 4 18.289 ns 0.3919 ns 0.7067 ns 18.407 ns 1.00 0.00
IndexOfAny_byte_ROS PR 8 4 11.070 ns 0.2500 ns 0.5107 ns 11.093 ns 0.61 0.04
IndexOfAny_byte_ROS main 8 5 21.680 ns 0.4553 ns 0.5592 ns 21.706 ns 1.00 0.00
IndexOfAny_byte_ROS PR 8 5 10.146 ns 0.2242 ns 0.2399 ns 10.126 ns 0.47 0.02
IndexOfAny_byte_ROS main 64 1 40.300 ns 0.2855 ns 0.2670 ns 40.281 ns 1.00 0.00
IndexOfAny_byte_ROS PR 64 1 4.416 ns 0.1032 ns 0.0966 ns 4.435 ns 0.11 0.00
IndexOfAny_byte_ROS main 64 2 4.104 ns 0.1106 ns 0.1786 ns 4.115 ns 1.00 0.00
IndexOfAny_byte_ROS PR 64 2 5.404 ns 0.1132 ns 0.1059 ns 5.400 ns 1.32 0.07
IndexOfAny_byte_ROS main 64 3 5.657 ns 0.1084 ns 0.1014 ns 5.677 ns 1.00 0.00
IndexOfAny_byte_ROS PR 64 3 5.975 ns 0.1438 ns 0.2196 ns 6.006 ns 1.06 0.04
IndexOfAny_byte_ROS main 64 4 98.455 ns 1.2650 ns 1.1833 ns 98.209 ns 1.00 0.00
IndexOfAny_byte_ROS PR 64 4 7.705 ns 0.1821 ns 0.4364 ns 7.683 ns 0.08 0.00
IndexOfAny_byte_ROS main 64 5 111.305 ns 0.5146 ns 0.4814 ns 111.450 ns 1.00 0.00
IndexOfAny_byte_ROS PR 64 5 8.245 ns 0.1912 ns 0.3448 ns 8.240 ns 0.07 0.00
IndexOfAny_byte_ROS main 1024 1 550.750 ns 0.4103 ns 0.3427 ns 550.611 ns 1.00 0.00
IndexOfAny_byte_ROS PR 1024 1 16.185 ns 0.1722 ns 0.1611 ns 16.210 ns 0.03 0.00
IndexOfAny_byte_ROS main 1024 2 18.040 ns 0.3859 ns 0.6657 ns 17.858 ns 1.00 0.00
IndexOfAny_byte_ROS PR 1024 2 20.046 ns 0.4286 ns 0.4936 ns 20.117 ns 1.11 0.05
IndexOfAny_byte_ROS main 1024 3 22.593 ns 0.3136 ns 0.2934 ns 22.444 ns 1.00 0.00
IndexOfAny_byte_ROS PR 1024 3 22.648 ns 0.4287 ns 0.4011 ns 22.742 ns 1.00 0.03
IndexOfAny_byte_ROS main 1024 4 1,378.781 ns 5.7639 ns 5.3915 ns 1,379.800 ns 1.00 0.00
IndexOfAny_byte_ROS PR 1024 4 30.109 ns 0.6085 ns 0.5692 ns 30.250 ns 0.02 0.00
IndexOfAny_byte_ROS main 1024 5 1,648.225 ns 3.7257 ns 3.1112 ns 1,648.891 ns 1.00 0.00
IndexOfAny_byte_ROS PR 1024 5 30.211 ns 0.4717 ns 0.4412 ns 30.297 ns 0.02 0.00
LastIndexOf_char_Span main 8 1 4.632 ns 0.0077 ns 0.0072 ns 4.630 ns 1.00 0.00
LastIndexOf_char_Span PR 8 1 4.694 ns 0.1110 ns 0.1695 ns 4.716 ns 1.01 0.05
LastIndexOf_char_Span main 8 2 6.081 ns 0.0035 ns 0.0029 ns 6.080 ns 1.00 0.00
LastIndexOf_char_Span PR 8 2 6.635 ns 0.0105 ns 0.0088 ns 6.637 ns 1.09 0.00
LastIndexOf_char_Span main 8 3 5.761 ns 0.0049 ns 0.0046 ns 5.763 ns 1.00 0.00
LastIndexOf_char_Span PR 8 3 6.268 ns 0.0124 ns 0.0104 ns 6.266 ns 1.09 0.00
LastIndexOf_char_Span main 8 4 5.221 ns 0.0063 ns 0.0059 ns 5.220 ns 1.00 0.00
LastIndexOf_char_Span PR 8 4 6.004 ns 0.0035 ns 0.0032 ns 6.005 ns 1.15 0.00
LastIndexOf_char_Span main 8 5 4.617 ns 0.0015 ns 0.0011 ns 4.617 ns 1.00 0.00
LastIndexOf_char_Span PR 8 5 5.771 ns 0.0028 ns 0.0025 ns 5.770 ns 1.25 0.00
LastIndexOf_char_Span main 64 1 17.617 ns 0.0112 ns 0.0099 ns 17.616 ns 1.00 0.00
LastIndexOf_char_Span PR 64 1 5.610 ns 0.0049 ns 0.0043 ns 5.611 ns 0.32 0.00
LastIndexOf_char_Span main 64 2 19.020 ns 0.0119 ns 0.0112 ns 19.022 ns 1.00 0.00
LastIndexOf_char_Span PR 64 2 7.238 ns 0.0725 ns 0.0642 ns 7.253 ns 0.38 0.00
LastIndexOf_char_Span main 64 3 18.526 ns 0.0131 ns 0.0110 ns 18.524 ns 1.00 0.00
LastIndexOf_char_Span PR 64 3 7.215 ns 0.0510 ns 0.0477 ns 7.188 ns 0.39 0.00
LastIndexOf_char_Span main 64 4 18.194 ns 0.0127 ns 0.0113 ns 18.192 ns 1.00 0.00
LastIndexOf_char_Span PR 64 4 7.288 ns 0.0711 ns 0.0665 ns 7.296 ns 0.40 0.00
LastIndexOf_char_Span main 64 5 18.095 ns 0.0253 ns 0.0237 ns 18.097 ns 1.00 0.00
LastIndexOf_char_Span PR 64 5 7.137 ns 0.0529 ns 0.0495 ns 7.142 ns 0.39 0.00
LastIndexOf_char_Span main 1024 1 220.402 ns 0.2264 ns 0.2118 ns 220.303 ns 1.00 0.00
LastIndexOf_char_Span PR 1024 1 29.481 ns 0.0918 ns 0.0858 ns 29.499 ns 0.13 0.00
LastIndexOf_char_Span main 1024 2 219.591 ns 0.3893 ns 0.3451 ns 219.559 ns 1.00 0.00
LastIndexOf_char_Span PR 1024 2 59.159 ns 0.7284 ns 0.6813 ns 59.171 ns 0.27 0.00
LastIndexOf_char_Span main 1024 3 218.000 ns 0.1500 ns 0.1403 ns 217.961 ns 1.00 0.00
LastIndexOf_char_Span PR 1024 3 59.667 ns 0.3749 ns 0.3323 ns 59.617 ns 0.27 0.00
LastIndexOf_char_Span main 1024 4 220.605 ns 0.0831 ns 0.0737 ns 220.620 ns 1.00 0.00
LastIndexOf_char_Span PR 1024 4 59.760 ns 0.4245 ns 0.3763 ns 59.789 ns 0.27 0.00
LastIndexOf_char_Span main 1024 5 219.007 ns 0.1947 ns 0.1626 ns 219.009 ns 1.00 0.00
LastIndexOf_char_Span PR 1024 5 59.505 ns 0.5208 ns 0.4871 ns 59.411 ns 0.27 0.00
LastIndexOfAny_byte_ROS main 8 1 8.740 ns 0.1974 ns 0.2027 ns 8.756 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 8 1 5.412 ns 0.1336 ns 0.1641 ns 5.431 ns 0.62 0.02
LastIndexOfAny_byte_ROS main 8 2 6.840 ns 0.1583 ns 0.2059 ns 6.875 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 8 2 8.224 ns 0.1198 ns 0.1062 ns 8.235 ns 1.21 0.05
LastIndexOfAny_byte_ROS main 8 3 9.525 ns 0.2188 ns 0.3341 ns 9.553 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 8 3 9.984 ns 0.2122 ns 0.1985 ns 9.950 ns 1.05 0.05
LastIndexOfAny_byte_ROS main 8 4 16.621 ns 0.3242 ns 0.3033 ns 16.816 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 8 4 11.422 ns 0.2458 ns 0.3108 ns 11.439 ns 0.69 0.02
LastIndexOfAny_byte_ROS main 8 5 17.627 ns 0.1521 ns 0.1422 ns 17.653 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 8 5 18.195 ns 0.1369 ns 0.1281 ns 18.194 ns 1.03 0.01
LastIndexOfAny_byte_ROS main 64 1 38.750 ns 0.2145 ns 0.2006 ns 38.723 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 64 1 4.607 ns 0.1005 ns 0.0891 ns 4.613 ns 0.12 0.00
LastIndexOfAny_byte_ROS main 64 2 4.612 ns 0.1186 ns 0.1584 ns 4.656 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 64 2 5.156 ns 0.0731 ns 0.0684 ns 5.193 ns 1.12 0.04
LastIndexOfAny_byte_ROS main 64 3 5.537 ns 0.1178 ns 0.1102 ns 5.542 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 64 3 6.040 ns 0.1475 ns 0.3012 ns 6.163 ns 1.08 0.07
LastIndexOfAny_byte_ROS main 64 4 98.505 ns 0.6669 ns 0.6238 ns 98.666 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 64 4 7.229 ns 0.1715 ns 0.3424 ns 7.249 ns 0.07 0.00
LastIndexOfAny_byte_ROS main 64 5 109.523 ns 0.1604 ns 0.1500 ns 109.560 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 64 5 111.629 ns 0.1737 ns 0.1624 ns 111.664 ns 1.02 0.00
LastIndexOfAny_byte_ROS main 1024 1 548.149 ns 0.4610 ns 0.4313 ns 548.020 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 1024 1 17.031 ns 0.0456 ns 0.0426 ns 17.028 ns 0.03 0.00
LastIndexOfAny_byte_ROS main 1024 2 20.863 ns 0.3697 ns 0.3458 ns 20.693 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 1024 2 18.833 ns 0.2013 ns 0.1883 ns 18.859 ns 0.90 0.02
LastIndexOfAny_byte_ROS main 1024 3 21.567 ns 0.2792 ns 0.2612 ns 21.573 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 1024 3 21.688 ns 0.4454 ns 0.4766 ns 21.688 ns 1.00 0.03
LastIndexOfAny_byte_ROS main 1024 4 1,371.158 ns 8.6512 ns 8.0923 ns 1,372.419 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 1024 4 29.946 ns 0.3665 ns 0.3428 ns 30.049 ns 0.02 0.00
LastIndexOfAny_byte_ROS main 1024 5 1,644.423 ns 2.4255 ns 2.2688 ns 1,644.547 ns 1.00 0.00
LastIndexOfAny_byte_ROS PR 1024 5 1,691.436 ns 39.6828 ns 105.9215 ns 1,646.512 ns 1.07 0.11
LastIndexOfAny_byte_Span main 8 1 7.177 ns 0.0663 ns 0.0621 ns 7.179 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 8 1 5.121 ns 0.0870 ns 0.0771 ns 5.122 ns 0.71 0.02
LastIndexOfAny_byte_Span main 8 2 10.563 ns 0.1535 ns 0.1436 ns 10.639 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 8 2 9.301 ns 0.2136 ns 0.4012 ns 9.432 ns 0.88 0.04
LastIndexOfAny_byte_Span main 8 3 13.617 ns 0.2393 ns 0.2238 ns 13.631 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 8 3 10.058 ns 0.1335 ns 0.1183 ns 10.039 ns 0.74 0.01
LastIndexOfAny_byte_Span main 8 4 16.143 ns 0.2179 ns 0.2038 ns 16.174 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 8 4 12.045 ns 0.1427 ns 0.1265 ns 12.010 ns 0.75 0.01
LastIndexOfAny_byte_Span main 8 5 17.577 ns 0.1953 ns 0.1631 ns 17.554 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 8 5 26.138 ns 0.7270 ns 2.1437 ns 27.469 ns 1.45 0.12
LastIndexOfAny_byte_Span main 64 1 38.526 ns 0.1101 ns 0.1030 ns 38.559 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 64 1 4.531 ns 0.0941 ns 0.0880 ns 4.552 ns 0.12 0.00
LastIndexOfAny_byte_Span main 64 2 59.828 ns 0.1546 ns 0.1291 ns 59.875 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 64 2 5.825 ns 0.1112 ns 0.1041 ns 5.802 ns 0.10 0.00
LastIndexOfAny_byte_Span main 64 3 78.977 ns 1.6081 ns 1.7207 ns 78.920 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 64 3 6.372 ns 0.1522 ns 0.2665 ns 6.466 ns 0.08 0.00
LastIndexOfAny_byte_Span main 64 4 92.914 ns 0.2358 ns 0.2206 ns 92.887 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 64 4 7.106 ns 0.1092 ns 0.1021 ns 7.093 ns 0.08 0.00
LastIndexOfAny_byte_Span main 64 5 115.788 ns 0.4738 ns 0.4200 ns 115.776 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 64 5 178.753 ns 2.8791 ns 2.4042 ns 178.450 ns 1.54 0.02
LastIndexOfAny_byte_Span main 1024 1 546.179 ns 0.7525 ns 0.7039 ns 546.434 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 1024 1 15.804 ns 0.2782 ns 0.2603 ns 15.831 ns 0.03 0.00
LastIndexOfAny_byte_Span main 1024 2 826.460 ns 0.4934 ns 0.4374 ns 826.339 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 1024 2 22.172 ns 0.4427 ns 0.4546 ns 22.202 ns 0.03 0.00
LastIndexOfAny_byte_Span main 1024 3 1,116.313 ns 13.1206 ns 12.2730 ns 1,118.085 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 1024 3 23.311 ns 0.4563 ns 0.4268 ns 23.179 ns 0.02 0.00
LastIndexOfAny_byte_Span main 1024 4 1,377.804 ns 8.4186 ns 7.8747 ns 1,377.064 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 1024 4 30.467 ns 0.1921 ns 0.1703 ns 30.499 ns 0.02 0.00
LastIndexOfAny_byte_Span main 1024 5 1,639.299 ns 3.6586 ns 3.4223 ns 1,639.443 ns 1.00 0.00
LastIndexOfAny_byte_Span PR 1024 5 1,639.896 ns 2.3544 ns 2.0871 ns 1,639.982 ns 1.00 0.00
LastIndexOfAny_char_ROS main 8 1 4.176 ns 0.1122 ns 0.2753 ns 4.304 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 8 1 4.118 ns 0.1111 ns 0.2908 ns 4.198 ns 0.99 0.09
LastIndexOfAny_char_ROS main 8 2 4.153 ns 0.1100 ns 0.1391 ns 4.225 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 8 2 4.123 ns 0.1131 ns 0.2336 ns 4.225 ns 1.00 0.06
LastIndexOfAny_char_ROS main 8 3 5.568 ns 0.1368 ns 0.1827 ns 5.593 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 8 3 5.579 ns 0.1354 ns 0.1854 ns 5.606 ns 1.00 0.05
LastIndexOfAny_char_ROS main 8 4 5.926 ns 0.1444 ns 0.2452 ns 5.906 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 8 4 6.054 ns 0.1478 ns 0.2345 ns 6.197 ns 1.02 0.06
LastIndexOfAny_char_ROS main 8 5 30.105 ns 0.3593 ns 0.3361 ns 30.278 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 8 5 28.813 ns 0.1247 ns 0.1166 ns 28.858 ns 0.96 0.01
LastIndexOfAny_char_ROS main 64 1 5.117 ns 0.1311 ns 0.3500 ns 5.114 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 64 1 5.322 ns 0.1344 ns 0.2093 ns 5.392 ns 1.04 0.10
LastIndexOfAny_char_ROS main 64 2 5.861 ns 0.1349 ns 0.1261 ns 5.918 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 64 2 5.945 ns 0.1455 ns 0.1361 ns 5.968 ns 1.01 0.03
LastIndexOfAny_char_ROS main 64 3 8.693 ns 0.2009 ns 0.2945 ns 8.722 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 64 3 8.670 ns 0.1939 ns 0.2233 ns 8.704 ns 1.00 0.06
LastIndexOfAny_char_ROS main 64 4 9.198 ns 0.2122 ns 0.4746 ns 9.419 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 64 4 9.363 ns 0.2149 ns 0.4763 ns 9.568 ns 1.02 0.08
LastIndexOfAny_char_ROS main 64 5 165.454 ns 0.4546 ns 0.4253 ns 165.417 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 64 5 163.399 ns 0.1426 ns 0.1334 ns 163.397 ns 0.99 0.00
LastIndexOfAny_char_ROS main 1024 1 30.605 ns 0.4445 ns 0.4158 ns 30.534 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 1024 1 30.494 ns 0.6011 ns 0.5623 ns 30.541 ns 1.00 0.02
LastIndexOfAny_char_ROS main 1024 2 35.341 ns 0.3629 ns 0.3395 ns 35.478 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 1024 2 35.433 ns 0.2929 ns 0.2740 ns 35.524 ns 1.00 0.01
LastIndexOfAny_char_ROS main 1024 3 51.550 ns 0.1107 ns 0.0981 ns 51.550 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 1024 3 51.553 ns 0.2292 ns 0.2032 ns 51.633 ns 1.00 0.00
LastIndexOfAny_char_ROS main 1024 4 52.702 ns 0.5584 ns 0.5223 ns 52.951 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 1024 4 52.687 ns 0.6479 ns 0.6061 ns 52.992 ns 1.00 0.02
LastIndexOfAny_char_ROS main 1024 5 2,402.390 ns 6.0446 ns 5.6541 ns 2,400.650 ns 1.00 0.00
LastIndexOfAny_char_ROS PR 1024 5 2,400.704 ns 3.5544 ns 2.9681 ns 2,399.535 ns 1.00 0.00
LastIndexOfAny_char_Span main 8 1 6.727 ns 0.0787 ns 0.0698 ns 6.737 ns 1.00 0.00
LastIndexOfAny_char_Span PR 8 1 3.637 ns 0.1023 ns 0.3015 ns 3.727 ns 0.55 0.05
LastIndexOfAny_char_Span main 8 2 8.841 ns 0.0080 ns 0.0075 ns 8.840 ns 1.00 0.00
LastIndexOfAny_char_Span PR 8 2 4.405 ns 0.1111 ns 0.1628 ns 4.505 ns 0.49 0.02
LastIndexOfAny_char_Span main 8 3 11.014 ns 0.0100 ns 0.0089 ns 11.012 ns 1.00 0.00
LastIndexOfAny_char_Span PR 8 3 5.497 ns 0.1366 ns 0.2663 ns 5.504 ns 0.49 0.02
LastIndexOfAny_char_Span main 8 4 12.962 ns 0.0631 ns 0.0590 ns 12.944 ns 1.00 0.00
LastIndexOfAny_char_Span PR 8 4 6.496 ns 0.1553 ns 0.1789 ns 6.500 ns 0.50 0.01
LastIndexOfAny_char_Span main 8 5 15.172 ns 0.0622 ns 0.0581 ns 15.181 ns 1.00 0.00
LastIndexOfAny_char_Span PR 8 5 29.214 ns 0.1136 ns 0.1062 ns 29.259 ns 1.93 0.01
LastIndexOfAny_char_Span main 64 1 37.689 ns 0.0323 ns 0.0302 ns 37.682 ns 1.00 0.00
LastIndexOfAny_char_Span PR 64 1 4.564 ns 0.1197 ns 0.2218 ns 4.643 ns 0.12 0.01
LastIndexOfAny_char_Span main 64 2 58.640 ns 0.1044 ns 0.0925 ns 58.613 ns 1.00 0.00
LastIndexOfAny_char_Span PR 64 2 5.953 ns 0.0897 ns 0.0700 ns 5.974 ns 0.10 0.00
LastIndexOfAny_char_Span main 64 3 76.896 ns 0.4778 ns 0.4469 ns 76.845 ns 1.00 0.00
LastIndexOfAny_char_Span PR 64 3 9.166 ns 0.2175 ns 0.6414 ns 9.171 ns 0.12 0.01
LastIndexOfAny_char_Span main 64 4 91.639 ns 0.3216 ns 0.3009 ns 91.635 ns 1.00 0.00
LastIndexOfAny_char_Span PR 64 4 10.127 ns 0.1005 ns 0.0940 ns 10.151 ns 0.11 0.00
LastIndexOfAny_char_Span main 64 5 109.354 ns 0.2167 ns 0.2027 ns 109.332 ns 1.00 0.00
LastIndexOfAny_char_Span PR 64 5 165.458 ns 1.4240 ns 1.3320 ns 165.469 ns 1.51 0.01
LastIndexOfAny_char_Span main 1024 1 552.382 ns 0.2771 ns 0.2314 ns 552.404 ns 1.00 0.00
LastIndexOfAny_char_Span PR 1024 1 29.888 ns 0.1588 ns 0.1486 ns 29.938 ns 0.05 0.00
LastIndexOfAny_char_Span main 1024 2 826.694 ns 0.8303 ns 0.7767 ns 826.598 ns 1.00 0.00
LastIndexOfAny_char_Span PR 1024 2 32.428 ns 0.0896 ns 0.0838 ns 32.427 ns 0.04 0.00
LastIndexOfAny_char_Span main 1024 3 1,418.347 ns 86.3344 ns 254.5588 ns 1,636.604 ns 1.00 0.00
LastIndexOfAny_char_Span PR 1024 3 52.653 ns 0.6295 ns 0.5888 ns 52.679 ns 0.04 0.01
LastIndexOfAny_char_Span main 1024 4 1,373.643 ns 6.0041 ns 5.0137 ns 1,373.256 ns 1.00 0.00
LastIndexOfAny_char_Span PR 1024 4 52.931 ns 0.3968 ns 0.3712 ns 52.740 ns 0.04 0.00
LastIndexOfAny_char_Span main 1024 5 1,659.335 ns 2.3113 ns 1.8045 ns 1,659.399 ns 1.00 0.00
LastIndexOfAny_char_Span PR 1024 5 2,408.283 ns 8.3724 ns 7.8315 ns 2,405.072 ns 1.45 0.00
public class PrValidation
{
    [Params(8, 64, 1024)]
    public int SearchSpaceCount;

    [Params(1, 2, 3, 4, 5)]
    public int ValueSpaceCount;

    private byte[] _searchSpaceBytes, _valueSpaceBytes;
    private char[] _searchSpaceChars, _valueSpaceChars;

    [GlobalSetup]
    public void Setup()
    {
        _searchSpaceBytes = new byte[SearchSpaceCount];
        _searchSpaceChars = new char[SearchSpaceCount];

        _valueSpaceBytes = Enumerable.Range(1, ValueSpaceCount).Select(Convert.ToByte).ToArray();
        _valueSpaceChars = Enumerable.Range(1, ValueSpaceCount).Select(Convert.ToChar).ToArray();
    }

    [Benchmark] public void LastIndexOf_char_Span() => new Span<char>(_searchSpaceChars).LastIndexOf(_valueSpaceChars);

    [Benchmark] public void IndexOfAny_byte_ROS() => new ReadOnlySpan<byte>(_searchSpaceBytes).IndexOfAny(_valueSpaceBytes);

    [Benchmark] public void LastIndexOfAny_byte_Span() => new Span<byte>(_searchSpaceBytes).LastIndexOfAny(_valueSpaceBytes);
    [Benchmark] public void LastIndexOfAny_byte_ROS() => new ReadOnlySpan<byte>(_searchSpaceBytes).LastIndexOfAny(_valueSpaceBytes);
    
    [Benchmark] public void LastIndexOfAny_char_Span() => new Span<char>(_searchSpaceChars).LastIndexOfAny(_valueSpaceChars);
    [Benchmark] public void LastIndexOfAny_char_ROS() => new ReadOnlySpan<char>(_searchSpaceChars).LastIndexOfAny(_valueSpaceChars);
}

@Rob-Hague Rob-Hague marked this pull request as ready for review September 17, 2022 13:06
@Rob-Hague
Copy link
Contributor Author

Rob-Hague commented Sep 18, 2022

I ran some slightly more comprehensive benchmarks on LastIndexOfAny 5-value. Really the changes are just unifying the Span and ReadOnlySpan versions which I presume is supposed to be the case and I am only submitting them in the context of correcting a mistake rather than any optimisation opportunity. So the benchmarks are just for completeness sake (and curiosity).

BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22000.978/21H2)
AMD Ryzen 7 5700U with Radeon Graphics, 1 CPU, 16 logical and 8 physical cores
.NET SDK=8.0.100-alpha.1.22465.14
  [Host]     : .NET 8.0.0 (8.0.22.46215), X64 RyuJIT AVX2
  main : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2
  PR : .NET 8.0.0 (42.42.42.42424), X64 RyuJIT AVX2

Method Job SearchSpaceCount valueSpace Mean Error StdDev Median Ratio RatioSD
LastIndexOfAny_Span main 10 \r\n\t\\\" 27.804 ns 0.5796 ns 1.3082 ns 27.910 ns 1.00 0.00
LastIndexOfAny_Span PR 10 \r\n\t\\\" 16.236 ns 0.1208 ns 0.1130 ns 16.286 ns 0.60 0.03
LastIndexOfAny_ROS main 10 \r\n\t\\\" 15.309 ns 0.1546 ns 0.1447 ns 15.357 ns 1.00 0.00
LastIndexOfAny_ROS PR 10 \r\n\t\\\" 15.421 ns 0.1328 ns 0.1242 ns 15.466 ns 1.01 0.01
LastIndexOfAny_Span main 10 LWXYZ 27.230 ns 0.8606 ns 2.5374 ns 26.416 ns 1.00 0.00
LastIndexOfAny_Span PR 10 LWXYZ 17.270 ns 0.1064 ns 0.0996 ns 17.313 ns 0.66 0.05
LastIndexOfAny_ROS main 10 LWXYZ 16.384 ns 0.0820 ns 0.0767 ns 16.433 ns 1.00 0.00
LastIndexOfAny_ROS PR 10 LWXYZ 16.341 ns 0.1697 ns 0.1587 ns 16.401 ns 1.00 0.01
LastIndexOfAny_Span main 10 abcde 14.497 ns 0.1948 ns 0.1727 ns 14.422 ns 1.00 0.00
LastIndexOfAny_Span PR 10 abcde 16.428 ns 0.1138 ns 0.1065 ns 16.439 ns 1.13 0.02
LastIndexOfAny_ROS main 10 abcde 15.460 ns 0.1171 ns 0.1095 ns 15.515 ns 1.00 0.00
LastIndexOfAny_ROS PR 10 abcde 15.429 ns 0.1387 ns 0.1298 ns 15.469 ns 1.00 0.01
LastIndexOfAny_Span main 10 zzzzu 3.325 ns 0.0305 ns 0.0270 ns 3.323 ns 1.00 0.00
LastIndexOfAny_Span PR 10 zzzzu 12.517 ns 0.1053 ns 0.0985 ns 12.548 ns 3.77 0.05
LastIndexOfAny_ROS main 10 zzzzu 11.752 ns 0.1259 ns 0.1051 ns 11.768 ns 1.00 0.00
LastIndexOfAny_ROS PR 10 zzzzu 11.853 ns 0.2234 ns 0.2090 ns 11.757 ns 1.01 0.02
LastIndexOfAny_Span main 100 \r\n\t&quot; 250.333 ns 5.0276 ns 11.8508 ns 249.235 ns 1.00 0.00
LastIndexOfAny_Span PR 100 \r\n\t&quot; 82.828 ns 0.1629 ns 0.1360 ns 82.841 ns 0.33 0.02
LastIndexOfAny_ROS main 100 \r\n\t&quot; 75.268 ns 0.1356 ns 0.1268 ns 75.216 ns 1.00 0.00
LastIndexOfAny_ROS PR 100 \r\n\t&quot; 74.259 ns 0.1841 ns 0.1722 ns 74.271 ns 0.99 0.00
LastIndexOfAny_Span main 100 LWXYZ 295.952 ns 13.6564 ns 40.2662 ns 292.568 ns 1.00 0.00
LastIndexOfAny_Span PR 100 LWXYZ 87.481 ns 1.2991 ns 1.2152 ns 87.459 ns 0.35 0.04
LastIndexOfAny_ROS main 100 LWXYZ 79.039 ns 0.2940 ns 0.2750 ns 79.073 ns 1.00 0.00
LastIndexOfAny_ROS PR 100 LWXYZ 79.330 ns 0.4195 ns 0.3924 ns 79.323 ns 1.00 0.00
LastIndexOfAny_Span main 100 abcde 8.767 ns 0.1342 ns 0.1120 ns 8.772 ns 1.00 0.00
LastIndexOfAny_Span PR 100 abcde 13.302 ns 0.1049 ns 0.0981 ns 13.350 ns 1.52 0.03
LastIndexOfAny_ROS main 100 abcde 12.582 ns 0.1828 ns 0.1710 ns 12.606 ns 1.00 0.00
LastIndexOfAny_ROS PR 100 abcde 12.525 ns 0.1695 ns 0.1586 ns 12.584 ns 1.00 0.02
LastIndexOfAny_Span main 100 zzzzu 8.908 ns 0.2076 ns 0.5014 ns 9.091 ns 1.00 0.00
LastIndexOfAny_Span PR 100 zzzzu 13.690 ns 0.1475 ns 0.1380 ns 13.731 ns 1.54 0.10
LastIndexOfAny_ROS main 100 zzzzu 12.846 ns 0.2601 ns 0.2433 ns 12.949 ns 1.00 0.00
LastIndexOfAny_ROS PR 100 zzzzu 12.885 ns 0.1873 ns 0.1752 ns 12.920 ns 1.00 0.02
LastIndexOfAny_Span main 1000 \r\n\t&quot; 526.045 ns 4.8075 ns 4.2617 ns 527.380 ns 1.00 0.00
LastIndexOfAny_Span PR 1000 \r\n\t&quot; 207.644 ns 0.0942 ns 0.0787 ns 207.641 ns 0.39 0.00
LastIndexOfAny_ROS main 1000 \r\n\t&quot; 183.971 ns 0.3338 ns 0.2959 ns 184.048 ns 1.00 0.00
LastIndexOfAny_ROS PR 1000 \r\n\t&quot; 184.128 ns 0.2943 ns 0.2609 ns 184.171 ns 1.00 0.00
LastIndexOfAny_Span main 1000 LWXYZ 2,190.996 ns 145.3601 ns 428.5975 ns 2,315.091 ns 1.00 0.00
LastIndexOfAny_Span PR 1000 LWXYZ 640.646 ns 0.2470 ns 0.2311 ns 640.625 ns 0.28 0.02
LastIndexOfAny_ROS main 1000 LWXYZ 561.617 ns 0.5231 ns 0.4637 ns 561.710 ns 1.00 0.00
LastIndexOfAny_ROS PR 1000 LWXYZ 561.928 ns 0.3935 ns 0.3681 ns 561.968 ns 1.00 0.00
LastIndexOfAny_Span main 1000 abcde 10.516 ns 0.2370 ns 0.2910 ns 10.596 ns 1.00 0.00
LastIndexOfAny_Span PR 1000 abcde 14.389 ns 0.1549 ns 0.1449 ns 14.413 ns 1.37 0.04
LastIndexOfAny_ROS main 1000 abcde 13.649 ns 0.1730 ns 0.1618 ns 13.717 ns 1.00 0.00
LastIndexOfAny_ROS PR 1000 abcde 13.523 ns 0.2902 ns 0.2715 ns 13.618 ns 0.99 0.02
LastIndexOfAny_Span main 1000 zzzzu 11.171 ns 0.1732 ns 0.1621 ns 11.212 ns 1.00 0.00
LastIndexOfAny_Span PR 1000 zzzzu 15.124 ns 0.1184 ns 0.1108 ns 15.155 ns 1.35 0.02
LastIndexOfAny_ROS main 1000 zzzzu 14.606 ns 0.1404 ns 0.1313 ns 14.625 ns 1.00 0.00
LastIndexOfAny_ROS PR 1000 zzzzu 14.626 ns 0.1390 ns 0.1300 ns 14.686 ns 1.00 0.01
    public class LoremIpsum
    {
        [Params(10, 100, 1000)]
        public int SearchSpaceCount;

        private char[] _searchSpace;

        [GlobalSetup]
        public void Setup()
        {
            _searchSpace = _loremIpsum.AsSpan(0, SearchSpaceCount).ToArray();
        }

        [Benchmark]
        [ArgumentsSource(nameof(ValueSpaces))]
        public int LastIndexOfAny_Span(string valueSpace) => new Span<char>(_searchSpace).LastIndexOfAny(valueSpace);

        [Benchmark]
        [ArgumentsSource(nameof(ValueSpaces))]
        public int LastIndexOfAny_ROS(string valueSpace) => new ReadOnlySpan<char>(_searchSpace).LastIndexOfAny(valueSpace);

        public IEnumerable<object> ValueSpaces()
        {
            yield return "\r\n\t\\\""; // (-1, -1, 724) in _searchSpace.AsSpan(0, SearchSpaceCount)
            yield return "abcde"; // (3, 96, 996)
            yield return "zzzzu"; // (-1, 57, 899)
            yield return "LWXYZ"; // (0, 0, 101)
        }

        private readonly string _loremIpsum = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sodales orci at urna efficitur finibus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ultrices facilisis volutpat. Curabitur vel sollicitudin risus. Nunc tortor libero, pretium ut mi eu, finibus rutrum enim. Vivamus malesuada vel nunc eu faucibus. Aliquam volutpat ultrices risus non pellentesque. Vivamus dignissim augue non dignissim pellentesque. Duis a fermentum dui. Nullam quis vestibulum neque. Quisque euismod ligula in ex blandit, sed aliquam orci lacinia. Curabitur facilisis, ante cursus venenatis dictum, elit ante rutrum nibh, vitae maximus libero odio ac est. Aliquam dignissim eros quis congue convallis. Aenean et erat libero.

Donec sapien nisl, efficitur nec arcu non, convallis fringilla nunc. Aenean rhoncus, tortor quis imperdiet placerat, dui nibh accumsan felis, sed mattis odio lectus sed est. Nulla cursus dictum sodales. Maecenas eget ornare augue, sed aliquam mauris. Fusce vel nisl congue, porta elit et, semper lectus.";

    }

@Rob-Hague
Copy link
Contributor Author

ping @adamsitnik not sure if you saw this one (which was unfortunately timed amongst the other IndexOf fixes), or if you otherwise had any thoughts. Thanks

@adamsitnik adamsitnik self-assigned this Oct 26, 2022
Copy link
Member

@adamsitnik adamsitnik left a comment

Choose a reason for hiding this comment

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

Thank you for a very thoughtful audit of all MemoryExtensions overloads! And apologies for the delay in review.

The PR looks great to me, failures are unrelated. Merging!

@adamsitnik adamsitnik merged commit 3e40074 into dotnet:main Oct 26, 2022
@adamsitnik adamsitnik added the tenet-performance Performance related issue label Oct 26, 2022
@adamsitnik adamsitnik added this to the 8.0.0 milestone Oct 26, 2022
@@ -1478,18 +1518,8 @@ private static unsafe int IndexOfAnyProbabilistic(ref char searchSpace, int sear
/// </summary>
/// <param name="span">The span to search.</param>
/// <param name="values">The set of values to search for.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Copy link
Member

@MihaZupan MihaZupan Oct 26, 2022

Choose a reason for hiding this comment

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

@Rob-Hague @adamsitnik
Was this intentional?

For better or worse, the LastIndexOfAny(ROS) overload is marked with AggressiveInlining, so this Span overload will now be more expensive for const values.

At the very least, it's now even more inconsistent with other places (e.g. IndexOfAny).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was intentional in that it became consistent with many of the other Span to ROS forwards though I agree it is (now) inconsistent with IndexOfAny(Span, ROS). I probably overlooked that.

I also believed that the annotation was superfluous in such cases - I apologise for the assumption as I did not instrument that.

@AndyAyersMS
Copy link
Member

AndyAyersMS commented Nov 3, 2022

@ghost ghost locked as resolved and limited conversation to collaborators Dec 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Memory community-contribution Indicates that the PR has been added by a community member tenet-performance Performance related issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants