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

Extend Equals/StartsWith auto-vectorization for OrdinalIgnoreCase #66095

Merged
merged 10 commits into from Mar 9, 2022

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Mar 2, 2022

This PR adds OrdinalIgnoreCase support to #65288 by injecting x | ToLowerMask operation where ToLowerMask looks like this for e.g for "ab1-C" constant value:

  ConstanValue: [  a ][  b ][  1 ][  - ][  C ]
  ToLowerMask:  [0x20][0x20][0x00][0x00][0x20]

if the constant value contains at least one non-ASCII char (>127) - we give up on optimizing it.

Codegen example

bool Test1(string s) => s.Equals("System.Private.CoreLib.dll", StringComparison.OrdinalIgnoreCase);

bool Test2(ReadOnlySpan<char> s) => s.StartsWith("X86", StringComparison.OrdinalIgnoreCase);

New codegen:

; Method Tests:Test1(System.String):bool:this
G_M52821_IG01:
       C5F877               vzeroupper 
       837A081A             cmp      dword ptr [rdx+8], 26  ;;  if (s.Length != 26)
       7542                 jne      SHORT G_M52821_IG04
       C5FD10420C           vmovupd  ymm0, ymmword ptr[rdx+12]
       C5FDEB054A000000     vpor     ymm0, ymm0, ymmword ptr[reloc @RWD00]  ;;  ToLower
       C5FDEF0562000000     vpxor    ymm0, ymm0, ymmword ptr[reloc @RWD32]
       C5FD104A20           vmovupd  ymm1, ymmword ptr[rdx+32]
       C5F5EB0D75000000     vpor     ymm1, ymm1, ymmword ptr[reloc @RWD64]  ;;  ToLower
       C5F5EF0D8D000000     vpxor    ymm1, ymm1, ymmword ptr[reloc @RWD96]
       C5FDEBC1             vpor     ymm0, ymm0, ymm1
       C4E27D17C0           vptest   ymm0, ymm0
       0F94C0               sete     al
       0FB6C0               movzx    rax, al
       EB02                 jmp      SHORT G_M52821_IG05
G_M52821_IG04:              
       33C0                 xor      eax, eax
G_M52821_IG05:              
       0FB6C0               movzx    rax, al
       C5F877               vzeroupper 
       C3                   ret      

RWD00  	dq	0020002000200020h, 0020000000200020h, 0020002000200020h, 0020000000200020h
RWD32  	dq	0074007300790073h, 0070002E006D0065h, 0061007600690072h, 0063002E00650074h
RWD64  	dq	0020002000200020h, 0020002000200000h, 0020002000200020h, 0020002000200000h
RWD96  	dq	0065007400610076h, 0072006F0063002Eh, 00620069006C0065h, 006C006C0064002Eh
; Total bytes of code: 77


; Method Tests:Test2(System.ReadOnlySpan`1[Char]):bool:this
G_M38726_IG01:
       488B02               mov      rax, bword ptr [rdx]
       837A0803             cmp      dword ptr [rdx+8], 3  ;;  if (s.Length < 3)
       7C1D                 jl       SHORT G_M38726_IG04
       8B10                 mov      edx, dword ptr [rax]
       83CA20               or       edx, 32  ;;  ToLower
       81F278003800         xor      edx, 0x380078
       8B4002               mov      eax, dword ptr [rax+2]
       3538003600           xor      eax, 0x360038  ;; no need for ToLower here
       0BC2                 or       eax, edx
       0F94C0               sete     al
       0FB6C0               movzx    rax, al
       EB02                 jmp      SHORT G_M38726_IG05
G_M38726_IG04:              
       33C0                 xor      eax, eax
G_M38726_IG05:              
       0FB6C0               movzx    rax, al
       C3                   ret      
; Total bytes of code: 44

Benchmark

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

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

public class Benchmarks
{
    const StringComparison cmp = StringComparison.OrdinalIgnoreCase;

    [Benchmark]
    [Arguments("https://bing.com")]
    public bool StartsWithHttps(string s) => s.StartsWith("https://bing", cmp); // two V128s

    [Benchmark]
    [Arguments("XMLFILE")]
    public bool StartsWithXml(string s) => s.StartsWith("xml", cmp); // SWAR (two I32s)

    [Benchmark]
    [Arguments("system.private.corelib.dll")]
    public bool EqualsCoreLib(string s) => s.Equals("System.Private.CoreLib.dll", cmp); // two V256s
}
Method Toolchain Mean Error StdDev Ratio
StartsWithHttps \Core_Root\corerun.exe 5.7167 ns 0.0496 ns 0.0464 ns 10.47
StartsWithHttps \Core_Root_PR\corerun.exe 0.5459 ns 0.0021 ns 0.0017 ns 1.00
StartsWithXml \Core_Root\corerun.exe 4.9878 ns 0.0099 ns 0.0082 ns 11.58
StartsWithXml \Core_Root_PR\corerun.exe 0.4307 ns 0.0067 ns 0.0052 ns 1.00
EqualsCoreLib \Core_Root\corerun.exe 14.1401 ns 0.1850 ns 0.1544 ns 20.68
EqualsCoreLib \Core_Root_PR\corerun.exe 0.6825 ns 0.0238 ns 0.0211 ns 1.00

10-20x faster for these cases.

#65288 added tests which also cover OrdinalIgnoreCase but I might add more.

jit-diff -f --crossgen
Summary of Code Size diffs:
(Lower is better)

Total bytes of base: 40958483
Total bytes of diff: 40962283
Total bytes of delta: 3800 (0.01 % of base)
Total relative delta: NaN
    diff is a regression.
    relative diff is a regression.


Top file regressions (bytes):
         450 : Microsoft.Diagnostics.Tracing.TraceEvent.dasm (0.01% of base)
         295 : System.Net.Http.dasm (0.05% of base)
         283 : System.Private.CoreLib.dasm (0.01% of base)
         239 : System.Data.Common.dasm (0.02% of base)
         209 : System.Net.Primitives.dasm (0.34% of base)
         200 : System.DirectoryServices.AccountManagement.dasm (0.08% of base)
         172 : Newtonsoft.Json.dasm (0.03% of base)
         164 : Microsoft.Extensions.Configuration.EnvironmentVariables.dasm (7.10% of base)
         160 : Microsoft.CodeAnalysis.VisualBasic.dasm (0.00% of base)
         158 : System.DirectoryServices.dasm (0.04% of base)
         153 : System.Net.HttpListener.dasm (0.07% of base)
         124 : System.Net.Http.WinHttpHandler.dasm (0.14% of base)
         107 : System.Data.OleDb.dasm (0.04% of base)
          92 : Microsoft.DotNet.XUnitExtensions.dasm (0.57% of base)
          89 : Newtonsoft.Json.Bson.dasm (0.12% of base)
          86 : Microsoft.CodeAnalysis.CSharp.dasm (0.00% of base)
          85 : xunit.console.dasm (0.13% of base)
          85 : System.IO.Packaging.dasm (0.11% of base)
          78 : System.ComponentModel.Annotations.dasm (0.20% of base)
          78 : System.Private.Xml.dasm (0.00% of base)
          75 : Microsoft.CodeAnalysis.dasm (0.01% of base)
          71 : System.Runtime.Caching.dasm (0.12% of base)
          69 : System.Net.Requests.dasm (0.07% of base)
          65 : System.Net.WebClient.dasm (0.15% of base)
          64 : System.Net.WebHeaderCollection.dasm (0.45% of base)
          61 : System.Configuration.ConfigurationManager.dasm (0.02% of base)
          59 : CommandLine.dasm (0.04% of base)
          52 : System.Net.Mail.dasm (0.03% of base)
          45 : Microsoft.Extensions.Logging.EventSource.dasm (0.46% of base)
          42 : Microsoft.Extensions.Logging.Configuration.dasm (0.99% of base)
          42 : Microsoft.Extensions.DependencyModel.dasm (0.10% of base)
          36 : System.Drawing.Primitives.dasm (0.10% of base)
          24 : Microsoft.Extensions.Hosting.WindowsServices.dasm (0.52% of base)
          23 : Microsoft.Extensions.FileProviders.Physical.dasm (0.16% of base)
          23 : xunit.runner.utility.netcoreapp10.dasm (0.02% of base)
          18 : System.Security.Permissions.dasm (0.13% of base)
          16 : System.Net.Sockets.dasm (0.01% of base)
          16 : System.Net.NameResolution.dasm (0.06% of base)
          16 : System.Net.Ping.dasm (0.08% of base)
          14 : System.Private.Xml.Linq.dasm (0.01% of base)
          14 : System.CodeDom.dasm (0.01% of base)
           9 : System.Linq.Expressions.dasm (0.00% of base)
           9 : Microsoft.Extensions.Configuration.Xml.dasm (0.11% of base)
           6 : System.Drawing.Common.dasm (0.00% of base)
           6 : System.Private.DataContractSerialization.dasm (0.00% of base)

Top file improvements (bytes):
        -188 : System.Management.dasm (-0.06% of base)
         -55 : Microsoft.Extensions.Options.ConfigurationExtensions.dasm (-1.93% of base)
         -39 : System.Diagnostics.Process.dasm (-0.04% of base)
         -26 : System.Resources.Extensions.dasm (-0.09% of base)
         -20 : System.IO.FileSystem.AccessControl.dasm (-0.08% of base)
         -20 : System.IO.FileSystem.Watcher.dasm (-0.14% of base)
         -20 : System.IO.Ports.dasm (-0.04% of base)
         -14 : System.ComponentModel.TypeConverter.dasm (-0.01% of base)

53 total files with Code Size differences (8 improved, 45 regressed), 218 unchanged.

Top method regressions (bytes):
         164 (16.55% of base) : Microsoft.Extensions.Configuration.EnvironmentVariables.dasm - Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider:Load(System.Collections.IDictionary):this
         159 (31.80% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c__DisplayClass32_0:<SetupCallbacks>b__4(Microsoft.Diagnostics.Tracing.Parsers.Symbol.FileVersionTraceData):this
         159 (45.30% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c__DisplayClass32_0:<SetupCallbacks>b__5(Microsoft.Diagnostics.Tracing.Parsers.Symbol.ImageIDTraceData):this
         124 (41.06% of base) : System.Net.Http.WinHttpHandler.dasm - System.Net.Http.WinHttpResponseParser:ParseResponseHeaders(Interop+WinHttp+SafeWinHttpHandle,System.Net.Http.HttpResponseMessage,System.Char[],bool)
         119 (107.21% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSocksScheme(System.String):bool
         112 (15.69% of base) : System.Net.Primitives.dasm - System.Net.CredentialCache:Add(System.String,int,System.String,System.Net.NetworkCredential):this
         105 (31.63% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequest:get_IsWebSocketRequest():bool:this
         102 (45.33% of base) : System.Data.Common.dasm - System.Data.DataSet:DetermineSchemaSerializationMode(System.Xml.XmlReader):int:this
          97 (15.18% of base) : System.Net.Primitives.dasm - System.Net.CredentialCache:Add(System.Uri,System.String,System.Net.NetworkCredential):this
          95 (53.98% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SAMUtils:DirectoryEntryAsPrincipal(System.DirectoryServices.DirectoryEntry,System.DirectoryServices.AccountManagement.StoreCtx):System.DirectoryServices.AccountManagement.Principal
          93 (21.14% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.RegexConverter:ReadRegexObject(Newtonsoft.Json.JsonReader,Newtonsoft.Json.JsonSerializer):System.Text.RegularExpressions.Regex:this
          92 (42.59% of base) : Microsoft.DotNet.XUnitExtensions.dasm - Microsoft.DotNet.XUnitExtensions.DiscovererHelpers:.cctor()
          91 (14.99% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.VisualBasicCommandLineParser:ParseResourceDescription(System.String,System.String,System.String,System.Collections.Generic.IList`1[Microsoft.CodeAnalysis.Diagnostic],bool):Microsoft.CodeAnalysis.ResourceDescription
          89 (16.57% of base) : Newtonsoft.Json.Bson.dasm - Newtonsoft.Json.Bson.Converters.BsonDataRegexConverter:ReadRegexObject(Newtonsoft.Json.JsonReader,Newtonsoft.Json.JsonSerializer):System.Text.RegularExpressions.Regex:this
          86 (13.94% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser:ParseResourceDescription(System.String,System.String,System.String,System.Collections.Generic.IList`1[Microsoft.CodeAnalysis.Diagnostic],bool):Microsoft.CodeAnalysis.ResourceDescription
          85 (38.29% of base) : System.IO.Packaging.dasm - System.IO.Packaging.PackagingUtilities:PerformInitialReadAndVerifyEncoding(System.Xml.XmlReader)
          82 (41.21% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryEntryManager:GetCachedDirectoryEntry(System.String):System.DirectoryServices.DirectoryEntry:this
          78 (49.68% of base) : System.ComponentModel.Annotations.dasm - System.ComponentModel.DataAnnotations.UrlAttribute:IsValid(System.Object):bool:this
          75 (34.88% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - Microsoft.Diagnostics.Symbols.SymbolPathElement:get_IsRemote():bool:this
          69 (20.41% of base) : System.Private.CoreLib.dasm - System.Globalization.CultureData:get_DisplayName():System.String:this
          67 (43.51% of base) : System.Net.Http.dasm - DigestResponse:MustValueBeQuoted(System.String):bool
          65 (20.97% of base) : System.Net.Http.dasm - DigestResponse:Parse(System.String):this
          65 ( 5.99% of base) : System.Net.WebClient.dasm - System.Net.WebClient:OpenFileInternal(bool,System.String,byref,byref,byref,byref):this
          64 (32.00% of base) : System.Net.WebHeaderCollection.dasm - System.Net.HeaderInfoTable:IsDuringExpiresAttributeParsing(System.String):bool
          61 (210.34% of base) : System.Configuration.ConfigurationManager.dasm - System.Configuration.ClientConfigurationHost:System.Configuration.Internal.IInternalConfigClientHost.IsExeConfig(System.String):bool:this
          61 (35.06% of base) : System.Data.Common.dasm - System.Data.DefaultValueTypeConverter:ConvertFrom(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object):System.Object:this
          61 (37.65% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.ADStoreCtx:LastLogonFromLdapConverter(System.DirectoryServices.AccountManagement.dSPropertyCollection,System.String,System.DirectoryServices.AccountManagement.Principal,System.String)
          60 (153.85% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentityExtensions:IsWindowsRuntime(Microsoft.CodeAnalysis.AssemblyIdentity):bool
          60 (117.65% of base) : System.Data.Common.dasm - System.Data.SimpleType:CanHaveMaxLength():bool:this
          57 (37.01% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c:<ManagedProcess>b__1_0(Microsoft.Diagnostics.Tracing.Etlx.TraceLoadedModule):bool:this
          56 ( 7.87% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.KeyValuePairConverter:ReadJson(Newtonsoft.Json.JsonReader,System.Type,System.Object,Newtonsoft.Json.JsonSerializer):System.Object:this
          52 (20.72% of base) : System.Net.Mail.dasm - System.Net.Mime.MimePart:get_TransferEncoding():int:this
          51 (91.07% of base) : System.Private.CoreLib.dasm - System.OperatingSystem:IsOSPlatform(System.String):bool
          49 (59.76% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSupportedSecureScheme(System.String):bool
          45 ( 5.21% of base) : Microsoft.Extensions.Logging.EventSource.dasm - Microsoft.Extensions.Logging.EventSource.LoggingEventSource:ParseFilterSpec(System.String,int):Microsoft.Extensions.Logging.LoggerFilterRule[]
          45 ( 8.44% of base) : xunit.console.dasm - Xunit.XunitPackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Internal.Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          44 (18.26% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequestUriBuilder:GetPath(System.String):System.String
          44 (12.09% of base) : System.Net.Requests.dasm - System.Net.HttpWebRequest:InternalGetRequestStream():System.Threading.Tasks.Task`1[System.IO.Stream]:this
          44 ( 7.75% of base) : System.Private.CoreLib.dasm - System.Runtime.Loader.AssemblyDependencyResolver:ResolveAssemblyToPath(System.Reflection.AssemblyName):System.String:this
          42 (25.15% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentity:TryParsePublicKeyToken(System.String,byref):bool
          42 (11.73% of base) : Microsoft.Extensions.DependencyModel.dasm - Microsoft.Extensions.DependencyModel.Resolution.PackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          42 ( 8.42% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnection:get_Database():System.String:this
          42 ( 8.05% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnection:get_DataSource():System.String:this
          42 ( 4.16% of base) : System.Drawing.Primitives.dasm - System.Drawing.ColorTranslator:FromHtml(System.String):System.Drawing.Color
          42 (12.21% of base) : System.Management.dasm - System.Management.RelatedObjectQuery:.ctor(System.String):this
          42 (12.21% of base) : System.Management.dasm - System.Management.RelationshipQuery:.ctor(System.String):this
          42 (11.90% of base) : System.Management.dasm - System.Management.WqlEventQuery:.ctor(System.String):this
          41 (22.53% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryEntryManager:RemoveIfExists(System.String):this
          41 (17.23% of base) : System.Management.dasm - System.Management.IWbemClassObjectFreeThreaded:Get_(System.String,int,byref,byref,byref):int:this
          41 (10.99% of base) : System.Management.dasm - System.Management.PropertyData:RefreshPropertyInfo():this
          40 (10.75% of base) : xunit.console.dasm - Internal.Microsoft.Extensions.DependencyModel.Resolution.PackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Internal.Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          40 (17.86% of base) : System.Private.CoreLib.dasm - System.Reflection.AssemblyNameParser:ParseProcessorArchitecture(System.String):int:this
          40 (15.50% of base) : System.Private.CoreLib.dasm - System.Resources.ResourceManager:IsDefaultType(System.String,System.String):bool
          36 (15.52% of base) : System.Runtime.Caching.dasm - System.Runtime.Caching.MemoryCache:.ctor(System.String,System.Collections.Specialized.NameValueCollection):this
          35 (14.52% of base) : System.Runtime.Caching.dasm - System.Runtime.Caching.MemoryCache:.ctor(System.String,System.Collections.Specialized.NameValueCollection,bool):this
          33 (126.92% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSecureWebSocketScheme(System.String):bool
          32 ( 6.17% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequest:get_ContentLength64():long:this
          31 (35.23% of base) : CommandLine.dasm - CommandLine.Infrastructure.StringExtensions:IsBooleanString(System.String):bool
          31 ( 7.69% of base) : Microsoft.Extensions.Logging.Configuration.dasm - Microsoft.Extensions.Logging.LoggerFilterConfigureOptions:LoadRules(Microsoft.Extensions.Logging.LoggerFilterOptions,Microsoft.Extensions.Configuration.IConfigurationSection,System.String):this
          31 ( 4.25% of base) : System.Management.dasm - System.Management.ManagementClassGenerator:GetDateTimeType(System.Management.PropertyData,byref):bool:this
          30 ( 8.20% of base) : System.Management.dasm - System.Management.SelectQuery:.ctor(System.String):this
          27 (55.10% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol:get_IsEntryPointCandidate():bool:this
          26 ( 1.66% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.Parser:ParseXmlProcessingInstruction(int,Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.XmlWhitespaceChecker):Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.XmlProcessingInstructionSyntax:this
          25 ( 9.23% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SDSUtils:ConstructDnsDomainNameFromDn(System.String):System.String
          25 ( 6.44% of base) : System.Net.Requests.dasm - System.Net.FileWebRequest:CheckAndMarkAsyncGetRequestStreamPending():this
          24 (20.87% of base) : Microsoft.Extensions.Hosting.WindowsServices.dasm - Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceHelpers:IsWindowsService():bool
          23 ( 2.67% of base) : xunit.runner.utility.netcoreapp10.dasm - <>c__DisplayClass6_0:<GetTypeNameForSerialization>g__GetTypeNameAsString|0(System.Type):System.String:this
          23 (56.10% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentityExtensions:IsWindowsComponent(Microsoft.CodeAnalysis.AssemblyIdentity):bool
          23 (17.29% of base) : Microsoft.Extensions.FileProviders.Physical.dasm - Microsoft.Extensions.FileProviders.PhysicalFileProvider:ReadPollingEnvironmentVariables():this
          23 ( 3.75% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.XmlNodeConverter:DeserializeValue(Newtonsoft.Json.JsonReader,Newtonsoft.Json.Converters.IXmlDocument,System.Xml.XmlNamespaceManager,System.String,Newtonsoft.Json.Converters.IXmlNode):this
          23 ( 4.68% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnectionString:.ctor(System.String,bool):this
          19 (67.86% of base) : CommandLine.dasm - CommandLine.Infrastructure.StringExtensions:ToBoolean(System.String):bool
          19 (19.79% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseHashAlgorithmName(System.String):int:this
          19 (67.86% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SDSUtils:IsObjectFromGC(System.String):bool
          19 ( 7.82% of base) : System.Private.CoreLib.dasm - System.TimeZoneInfo:.ctor(System.String,System.TimeSpan,System.String,System.String,System.String,System.TimeZoneInfo+AdjustmentRule[],bool,bool):this
          19 (18.27% of base) : System.Private.Xml.dasm - System.Xml.XmlImplementation:HasFeature(System.String,System.String):bool:this
          19 (18.27% of base) : System.Private.Xml.dasm - System.Xml.XmlNode:Supports(System.String,System.String):bool:this
          18 (31.03% of base) : System.Net.Http.dasm - System.Net.Http.HttpClient:ShouldBufferResponse(int,System.Net.Http.HttpRequestMessage):bool
          18 (11.69% of base) : System.Security.Permissions.dasm - System.Security.Permissions.IDRole:.ctor(System.Security.SecurityElement):this
          17 ( 1.23% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ActiveDirectorySite:GetLinks():this
          16 (61.54% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsNonSecureWebSocketScheme(System.String):bool
          16 (11.03% of base) : System.Net.Sockets.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          16 (11.03% of base) : System.Net.NameResolution.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          16 (11.03% of base) : System.Net.Ping.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          16 (25.00% of base) : System.Private.CoreLib.dasm - System.Reflection.AssemblyNameParser:ParseCulture(System.String):System.String:this
          16 ( 3.78% of base) : System.Private.Xml.dasm - System.Xml.XmlWellFormedWriter:WriteProcessingInstruction(System.String,System.String):this
          15 ( 9.20% of base) : Microsoft.CodeAnalysis.dasm - Roslyn.Utilities.PathUtilities:IsFilePath(System.String):bool
          14 ( 2.24% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory:Literal(Microsoft.CodeAnalysis.SyntaxTriviaList,System.String,int,Microsoft.CodeAnalysis.SyntaxTriviaList):Microsoft.CodeAnalysis.SyntaxToken (2 methods)
          14 ( 2.24% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory:Literal(Microsoft.CodeAnalysis.SyntaxTriviaList,System.String,long,Microsoft.CodeAnalysis.SyntaxTriviaList):Microsoft.CodeAnalysis.SyntaxToken (2 methods)
          14 ( 3.59% of base) : System.CodeDom.dasm - System.CodeDom.Compiler.CodeValidator:ValidateProperty(System.CodeDom.CodeMemberProperty):this
          14 ( 3.37% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ReplicationNeighbor:.ctor(long,System.DirectoryServices.ActiveDirectory.DirectoryServer,System.Collections.Hashtable):this
          14 ( 3.26% of base) : System.Net.Http.dasm - System.Net.Http.AuthenticationHelper:ComputeHash(System.String,System.String):System.String
          14 (12.07% of base) : System.Private.Xml.Linq.dasm - System.Xml.Linq.XProcessingInstruction:ValidateName(System.String)
          14 ( 4.79% of base) : System.Private.Xml.dasm - System.Xml.XmlTextWriter:WriteProcessingInstruction(System.String,System.String):this
          11 ( 2.64% of base) : Microsoft.Extensions.Logging.Configuration.dasm - Microsoft.Extensions.Logging.LoggerFilterConfigureOptions:LoadDefaultConfigValues(Microsoft.Extensions.Logging.LoggerFilterOptions):this
          10 ( 5.75% of base) : System.Private.Xml.dasm - System.Xml.Xsl.XsltOld.SequentialOutput:DecideDefaultOutput(System.Xml.Xsl.XsltOld.BuilderInfo):bool:this
           9 ( 3.91% of base) : CommandLine.dasm - <>c__DisplayClass3_0:<ChangeTypeScalarImpl>b__0():System.Object:this
           9 ( 3.88% of base) : Microsoft.Extensions.Configuration.Xml.dasm - Microsoft.Extensions.Configuration.Xml.XmlStreamConfigurationProvider:GetName(System.Xml.XmlReader):System.String
           9 ( 1.97% of base) : System.Linq.Expressions.dasm - System.Linq.Expressions.Expression:ValidateElementInitAddMethodInfo(System.Reflection.MethodInfo,System.String)
           9 ( 1.55% of base) : System.Private.CoreLib.dasm - System.TimeZoneInfo:FindSystemTimeZoneById(System.String):System.TimeZoneInfo

Top method improvements (bytes):
        -429 (-2.33% of base) : System.Management.dasm - System.Management.ManagementClassGenerator:GenerateMethods():this
         -80 (-2.49% of base) : System.Net.Http.dasm - <GetDigestTokenForCredential>d__40:MoveNext():this
         -42 (-19.72% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseUInt16(System.String,byref):bool
         -42 (-19.72% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseUInt64(System.String,byref):bool
         -39 (-12.96% of base) : System.Diagnostics.Process.dasm - System.Diagnostics.NtProcessInfoHelper:GetProcessShortName(System.ReadOnlySpan`1[System.Char]):System.String
         -28 (-28.28% of base) : Microsoft.Extensions.Options.ConfigurationExtensions.dasm - <>c__DisplayClass3_0`1:<BindConfiguration>b__0(System.__Canon,Microsoft.Extensions.Configuration.IConfiguration):this
         -28 (-4.06% of base) : System.Net.HttpListener.dasm - System.Net.ServiceNameStore:BuildServiceNames(System.String):System.String[]:this
         -27 (-28.72% of base) : Microsoft.Extensions.Options.ConfigurationExtensions.dasm - Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions:BindFromOptions(System.__Canon,Microsoft.Extensions.Configuration.IConfiguration,System.String,System.Action`1[Microsoft.Extensions.Configuration.BinderOptions])
         -26 (-32.91% of base) : System.Resources.Extensions.dasm - System.Resources.Extensions.TypeNameComparer:IsMscorlib(System.ReadOnlySpan`1[System.Char]):bool
         -22 (-4.57% of base) : System.Management.dasm - System.Management.WmiEventSink:.ctor(System.Management.ManagementOperationObserver,System.Object,System.Management.ManagementScope,System.String,System.String):this
         -20 (-9.57% of base) : System.IO.FileSystem.AccessControl.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -20 (-9.57% of base) : System.IO.FileSystem.Watcher.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -20 (-9.57% of base) : System.IO.Ports.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -16 (-8.16% of base) : System.Private.CoreLib.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -12 (-3.54% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.VisualBasicCommandLineParser:ParseBaseAddress(System.String,System.String,System.Collections.Generic.List`1[Microsoft.CodeAnalysis.Diagnostic]):long
         -11 (-2.84% of base) : System.Management.dasm - System.Management.SinkForEventQuery:.ctor(System.Management.ManagementEventWatcher,System.Object,System.Management.IWbemServices):this
         -10 (-15.15% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSupportedProxyScheme(System.String):bool
          -8 (-1.48% of base) : System.ComponentModel.TypeConverter.dasm - System.ComponentModel.BaseNumberConverter:ConvertFrom(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object):System.Object:this
          -6 (-1.62% of base) : System.ComponentModel.TypeConverter.dasm - System.Drawing.ColorConverterCommon:IntFromString(System.String,System.Globalization.CultureInfo):int
          -6 (-1.62% of base) : System.Drawing.Primitives.dasm - System.Drawing.ColorConverterCommon:IntFromString(System.String,System.Globalization.CultureInfo):int
          -3 (-1.71% of base) : System.Management.dasm - System.Management.ManagementPath:SetWbemPath(System.Management.IWbemPath,System.String)

Top method regressions (percentages):
          61 (210.34% of base) : System.Configuration.ConfigurationManager.dasm - System.Configuration.ClientConfigurationHost:System.Configuration.Internal.IInternalConfigClientHost.IsExeConfig(System.String):bool:this
          60 (153.85% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentityExtensions:IsWindowsRuntime(Microsoft.CodeAnalysis.AssemblyIdentity):bool
          33 (126.92% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSecureWebSocketScheme(System.String):bool
          60 (117.65% of base) : System.Data.Common.dasm - System.Data.SimpleType:CanHaveMaxLength():bool:this
         119 (107.21% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSocksScheme(System.String):bool
          51 (91.07% of base) : System.Private.CoreLib.dasm - System.OperatingSystem:IsOSPlatform(System.String):bool
          19 (67.86% of base) : CommandLine.dasm - CommandLine.Infrastructure.StringExtensions:ToBoolean(System.String):bool
          19 (67.86% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SDSUtils:IsObjectFromGC(System.String):bool
          16 (61.54% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsNonSecureWebSocketScheme(System.String):bool
          49 (59.76% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSupportedSecureScheme(System.String):bool
          23 (56.10% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentityExtensions:IsWindowsComponent(Microsoft.CodeAnalysis.AssemblyIdentity):bool
          27 (55.10% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.MethodSymbol:get_IsEntryPointCandidate():bool:this
          95 (53.98% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SAMUtils:DirectoryEntryAsPrincipal(System.DirectoryServices.DirectoryEntry,System.DirectoryServices.AccountManagement.StoreCtx):System.DirectoryServices.AccountManagement.Principal
          78 (49.68% of base) : System.ComponentModel.Annotations.dasm - System.ComponentModel.DataAnnotations.UrlAttribute:IsValid(System.Object):bool:this
         102 (45.33% of base) : System.Data.Common.dasm - System.Data.DataSet:DetermineSchemaSerializationMode(System.Xml.XmlReader):int:this
         159 (45.30% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c__DisplayClass32_0:<SetupCallbacks>b__5(Microsoft.Diagnostics.Tracing.Parsers.Symbol.ImageIDTraceData):this
          67 (43.51% of base) : System.Net.Http.dasm - DigestResponse:MustValueBeQuoted(System.String):bool
          92 (42.59% of base) : Microsoft.DotNet.XUnitExtensions.dasm - Microsoft.DotNet.XUnitExtensions.DiscovererHelpers:.cctor()
          82 (41.21% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryEntryManager:GetCachedDirectoryEntry(System.String):System.DirectoryServices.DirectoryEntry:this
         124 (41.06% of base) : System.Net.Http.WinHttpHandler.dasm - System.Net.Http.WinHttpResponseParser:ParseResponseHeaders(Interop+WinHttp+SafeWinHttpHandle,System.Net.Http.HttpResponseMessage,System.Char[],bool)
          85 (38.29% of base) : System.IO.Packaging.dasm - System.IO.Packaging.PackagingUtilities:PerformInitialReadAndVerifyEncoding(System.Xml.XmlReader)
          61 (37.65% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.ADStoreCtx:LastLogonFromLdapConverter(System.DirectoryServices.AccountManagement.dSPropertyCollection,System.String,System.DirectoryServices.AccountManagement.Principal,System.String)
          57 (37.01% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c:<ManagedProcess>b__1_0(Microsoft.Diagnostics.Tracing.Etlx.TraceLoadedModule):bool:this
          31 (35.23% of base) : CommandLine.dasm - CommandLine.Infrastructure.StringExtensions:IsBooleanString(System.String):bool
          61 (35.06% of base) : System.Data.Common.dasm - System.Data.DefaultValueTypeConverter:ConvertFrom(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object):System.Object:this
          75 (34.88% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - Microsoft.Diagnostics.Symbols.SymbolPathElement:get_IsRemote():bool:this
          64 (32.00% of base) : System.Net.WebHeaderCollection.dasm - System.Net.HeaderInfoTable:IsDuringExpiresAttributeParsing(System.String):bool
         159 (31.80% of base) : Microsoft.Diagnostics.Tracing.TraceEvent.dasm - <>c__DisplayClass32_0:<SetupCallbacks>b__4(Microsoft.Diagnostics.Tracing.Parsers.Symbol.FileVersionTraceData):this
         105 (31.63% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequest:get_IsWebSocketRequest():bool:this
          18 (31.03% of base) : System.Net.Http.dasm - System.Net.Http.HttpClient:ShouldBufferResponse(int,System.Net.Http.HttpRequestMessage):bool
          42 (25.15% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.AssemblyIdentity:TryParsePublicKeyToken(System.String,byref):bool
          16 (25.00% of base) : System.Private.CoreLib.dasm - System.Reflection.AssemblyNameParser:ParseCulture(System.String):System.String:this
          41 (22.53% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.DirectoryEntryManager:RemoveIfExists(System.String):this
          93 (21.14% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.RegexConverter:ReadRegexObject(Newtonsoft.Json.JsonReader,Newtonsoft.Json.JsonSerializer):System.Text.RegularExpressions.Regex:this
          65 (20.97% of base) : System.Net.Http.dasm - DigestResponse:Parse(System.String):this
          24 (20.87% of base) : Microsoft.Extensions.Hosting.WindowsServices.dasm - Microsoft.Extensions.Hosting.WindowsServices.WindowsServiceHelpers:IsWindowsService():bool
          52 (20.72% of base) : System.Net.Mail.dasm - System.Net.Mime.MimePart:get_TransferEncoding():int:this
          69 (20.41% of base) : System.Private.CoreLib.dasm - System.Globalization.CultureData:get_DisplayName():System.String:this
          19 (19.79% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseHashAlgorithmName(System.String):int:this
          19 (18.27% of base) : System.Private.Xml.dasm - System.Xml.XmlImplementation:HasFeature(System.String,System.String):bool:this
          19 (18.27% of base) : System.Private.Xml.dasm - System.Xml.XmlNode:Supports(System.String,System.String):bool:this
          44 (18.26% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequestUriBuilder:GetPath(System.String):System.String
          40 (17.86% of base) : System.Private.CoreLib.dasm - System.Reflection.AssemblyNameParser:ParseProcessorArchitecture(System.String):int:this
          23 (17.29% of base) : Microsoft.Extensions.FileProviders.Physical.dasm - Microsoft.Extensions.FileProviders.PhysicalFileProvider:ReadPollingEnvironmentVariables():this
          41 (17.23% of base) : System.Management.dasm - System.Management.IWbemClassObjectFreeThreaded:Get_(System.String,int,byref,byref,byref):int:this
          89 (16.57% of base) : Newtonsoft.Json.Bson.dasm - Newtonsoft.Json.Bson.Converters.BsonDataRegexConverter:ReadRegexObject(Newtonsoft.Json.JsonReader,Newtonsoft.Json.JsonSerializer):System.Text.RegularExpressions.Regex:this
         164 (16.55% of base) : Microsoft.Extensions.Configuration.EnvironmentVariables.dasm - Microsoft.Extensions.Configuration.EnvironmentVariables.EnvironmentVariablesConfigurationProvider:Load(System.Collections.IDictionary):this
         112 (15.69% of base) : System.Net.Primitives.dasm - System.Net.CredentialCache:Add(System.String,int,System.String,System.Net.NetworkCredential):this
          36 (15.52% of base) : System.Runtime.Caching.dasm - System.Runtime.Caching.MemoryCache:.ctor(System.String,System.Collections.Specialized.NameValueCollection):this
          40 (15.50% of base) : System.Private.CoreLib.dasm - System.Resources.ResourceManager:IsDefaultType(System.String,System.String):bool
          97 (15.18% of base) : System.Net.Primitives.dasm - System.Net.CredentialCache:Add(System.Uri,System.String,System.Net.NetworkCredential):this
          91 (14.99% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.VisualBasicCommandLineParser:ParseResourceDescription(System.String,System.String,System.String,System.Collections.Generic.IList`1[Microsoft.CodeAnalysis.Diagnostic],bool):Microsoft.CodeAnalysis.ResourceDescription
          35 (14.52% of base) : System.Runtime.Caching.dasm - System.Runtime.Caching.MemoryCache:.ctor(System.String,System.Collections.Specialized.NameValueCollection,bool):this
          86 (13.94% of base) : Microsoft.CodeAnalysis.CSharp.dasm - Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser:ParseResourceDescription(System.String,System.String,System.String,System.Collections.Generic.IList`1[Microsoft.CodeAnalysis.Diagnostic],bool):Microsoft.CodeAnalysis.ResourceDescription
          42 (12.21% of base) : System.Management.dasm - System.Management.RelatedObjectQuery:.ctor(System.String):this
          42 (12.21% of base) : System.Management.dasm - System.Management.RelationshipQuery:.ctor(System.String):this
          44 (12.09% of base) : System.Net.Requests.dasm - System.Net.HttpWebRequest:InternalGetRequestStream():System.Threading.Tasks.Task`1[System.IO.Stream]:this
          14 (12.07% of base) : System.Private.Xml.Linq.dasm - System.Xml.Linq.XProcessingInstruction:ValidateName(System.String)
          42 (11.90% of base) : System.Management.dasm - System.Management.WqlEventQuery:.ctor(System.String):this
          42 (11.73% of base) : Microsoft.Extensions.DependencyModel.dasm - Microsoft.Extensions.DependencyModel.Resolution.PackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          18 (11.69% of base) : System.Security.Permissions.dasm - System.Security.Permissions.IDRole:.ctor(System.Security.SecurityElement):this
          16 (11.03% of base) : System.Net.Sockets.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          16 (11.03% of base) : System.Net.NameResolution.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          16 (11.03% of base) : System.Net.Ping.dasm - System.Net.SocketProtocolSupportPal:IsIPv6Disabled():bool
          41 (10.99% of base) : System.Management.dasm - System.Management.PropertyData:RefreshPropertyInfo():this
          40 (10.75% of base) : xunit.console.dasm - Internal.Microsoft.Extensions.DependencyModel.Resolution.PackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Internal.Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          25 ( 9.23% of base) : System.DirectoryServices.AccountManagement.dasm - System.DirectoryServices.AccountManagement.SDSUtils:ConstructDnsDomainNameFromDn(System.String):System.String
          15 ( 9.20% of base) : Microsoft.CodeAnalysis.dasm - Roslyn.Utilities.PathUtilities:IsFilePath(System.String):bool
          45 ( 8.44% of base) : xunit.console.dasm - Xunit.XunitPackageCompilationAssemblyResolver:TryResolveAssemblyPaths(Internal.Microsoft.Extensions.DependencyModel.CompilationLibrary,System.Collections.Generic.List`1[System.String]):bool:this
          42 ( 8.42% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnection:get_Database():System.String:this
          30 ( 8.20% of base) : System.Management.dasm - System.Management.SelectQuery:.ctor(System.String):this
          42 ( 8.05% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnection:get_DataSource():System.String:this
          56 ( 7.87% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.KeyValuePairConverter:ReadJson(Newtonsoft.Json.JsonReader,System.Type,System.Object,Newtonsoft.Json.JsonSerializer):System.Object:this
          19 ( 7.82% of base) : System.Private.CoreLib.dasm - System.TimeZoneInfo:.ctor(System.String,System.TimeSpan,System.String,System.String,System.String,System.TimeZoneInfo+AdjustmentRule[],bool,bool):this
          44 ( 7.75% of base) : System.Private.CoreLib.dasm - System.Runtime.Loader.AssemblyDependencyResolver:ResolveAssemblyToPath(System.Reflection.AssemblyName):System.String:this
          31 ( 7.69% of base) : Microsoft.Extensions.Logging.Configuration.dasm - Microsoft.Extensions.Logging.LoggerFilterConfigureOptions:LoadRules(Microsoft.Extensions.Logging.LoggerFilterOptions,Microsoft.Extensions.Configuration.IConfigurationSection,System.String):this
          25 ( 6.44% of base) : System.Net.Requests.dasm - System.Net.FileWebRequest:CheckAndMarkAsyncGetRequestStreamPending():this
          32 ( 6.17% of base) : System.Net.HttpListener.dasm - System.Net.HttpListenerRequest:get_ContentLength64():long:this
          65 ( 5.99% of base) : System.Net.WebClient.dasm - System.Net.WebClient:OpenFileInternal(bool,System.String,byref,byref,byref,byref):this
          10 ( 5.75% of base) : System.Private.Xml.dasm - System.Xml.Xsl.XsltOld.SequentialOutput:DecideDefaultOutput(System.Xml.Xsl.XsltOld.BuilderInfo):bool:this
           6 ( 5.66% of base) : System.Management.dasm - System.Management.ManagementPath:IsValidNamespaceSyntax(System.String):bool
          45 ( 5.21% of base) : Microsoft.Extensions.Logging.EventSource.dasm - Microsoft.Extensions.Logging.EventSource.LoggingEventSource:ParseFilterSpec(System.String,int):Microsoft.Extensions.Logging.LoggerFilterRule[]
          14 ( 4.79% of base) : System.Private.Xml.dasm - System.Xml.XmlTextWriter:WriteProcessingInstruction(System.String,System.String):this
          23 ( 4.68% of base) : System.Data.OleDb.dasm - System.Data.OleDb.OleDbConnectionString:.ctor(System.String,bool):this
           2 ( 4.26% of base) : System.Management.dasm - System.Management.ManagementClassGenerator:IsDesignerSerializationVisibilityToBeSet(System.String):bool
          31 ( 4.25% of base) : System.Management.dasm - System.Management.ManagementClassGenerator:GetDateTimeType(System.Management.PropertyData,byref):bool:this
          42 ( 4.16% of base) : System.Drawing.Primitives.dasm - System.Drawing.ColorTranslator:FromHtml(System.String):System.Drawing.Color
           9 ( 3.91% of base) : CommandLine.dasm - <>c__DisplayClass3_0:<ChangeTypeScalarImpl>b__0():System.Object:this
           9 ( 3.88% of base) : Microsoft.Extensions.Configuration.Xml.dasm - Microsoft.Extensions.Configuration.Xml.XmlStreamConfigurationProvider:GetName(System.Xml.XmlReader):System.String
          16 ( 3.78% of base) : System.Private.Xml.dasm - System.Xml.XmlWellFormedWriter:WriteProcessingInstruction(System.String,System.String):this
          23 ( 3.75% of base) : Newtonsoft.Json.dasm - Newtonsoft.Json.Converters.XmlNodeConverter:DeserializeValue(Newtonsoft.Json.JsonReader,Newtonsoft.Json.Converters.IXmlDocument,System.Xml.XmlNamespaceManager,System.String,Newtonsoft.Json.Converters.IXmlNode):this
          14 ( 3.59% of base) : System.CodeDom.dasm - System.CodeDom.Compiler.CodeValidator:ValidateProperty(System.CodeDom.CodeMemberProperty):this
          14 ( 3.37% of base) : System.DirectoryServices.dasm - System.DirectoryServices.ActiveDirectory.ReplicationNeighbor:.ctor(long,System.DirectoryServices.ActiveDirectory.DirectoryServer,System.Collections.Hashtable):this
           8 ( 3.28% of base) : System.Data.Common.dasm - System.Data.XmlToDatasetMap:AddColumnSchema(System.Data.DataColumn,System.Xml.XmlNameTable,System.Data.XmlToDatasetMap+XmlNodeIdHashtable):bool:this
          14 ( 3.26% of base) : System.Net.Http.dasm - System.Net.Http.AuthenticationHelper:ComputeHash(System.String,System.String):System.String
           6 ( 3.02% of base) : System.Private.DataContractSerialization.dasm - System.Runtime.Serialization.Json.XmlJsonWriter:WriteProcessingInstruction(System.String,System.String):this
          23 ( 2.67% of base) : xunit.runner.utility.netcoreapp10.dasm - <>c__DisplayClass6_0:<GetTypeNameForSerialization>g__GetTypeNameAsString|0(System.Type):System.String:this
          11 ( 2.64% of base) : Microsoft.Extensions.Logging.Configuration.dasm - Microsoft.Extensions.Logging.LoggerFilterConfigureOptions:LoadDefaultConfigValues(Microsoft.Extensions.Logging.LoggerFilterOptions):this
           8 ( 2.47% of base) : System.Data.Common.dasm - System.Data.XmlToDatasetMap:AddColumnSchema(System.Xml.XmlNameTable,System.Data.DataColumn,System.Data.XmlToDatasetMap+XmlNodeIdHashtable):bool:this
           2 ( 2.44% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSupportedNonSecureScheme(System.String):bool

Top method improvements (percentages):
         -26 (-32.91% of base) : System.Resources.Extensions.dasm - System.Resources.Extensions.TypeNameComparer:IsMscorlib(System.ReadOnlySpan`1[System.Char]):bool
         -27 (-28.72% of base) : Microsoft.Extensions.Options.ConfigurationExtensions.dasm - Microsoft.Extensions.DependencyInjection.OptionsBuilderConfigurationExtensions:BindFromOptions(System.__Canon,Microsoft.Extensions.Configuration.IConfiguration,System.String,System.Action`1[Microsoft.Extensions.Configuration.BinderOptions])
         -28 (-28.28% of base) : Microsoft.Extensions.Options.ConfigurationExtensions.dasm - <>c__DisplayClass3_0`1:<BindConfiguration>b__0(System.__Canon,Microsoft.Extensions.Configuration.IConfiguration):this
         -42 (-19.72% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseUInt16(System.String,byref):bool
         -42 (-19.72% of base) : Microsoft.CodeAnalysis.dasm - Microsoft.CodeAnalysis.CommandLineParser:TryParseUInt64(System.String,byref):bool
         -10 (-15.15% of base) : System.Net.Http.dasm - System.Net.Http.HttpUtilities:IsSupportedProxyScheme(System.String):bool
         -39 (-12.96% of base) : System.Diagnostics.Process.dasm - System.Diagnostics.NtProcessInfoHelper:GetProcessShortName(System.ReadOnlySpan`1[System.Char]):System.String
         -20 (-9.57% of base) : System.IO.FileSystem.AccessControl.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -20 (-9.57% of base) : System.IO.FileSystem.Watcher.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -20 (-9.57% of base) : System.IO.Ports.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -16 (-8.16% of base) : System.Private.CoreLib.dasm - System.IO.PathInternal:EnsureExtendedPrefix(System.String):System.String
         -22 (-4.57% of base) : System.Management.dasm - System.Management.WmiEventSink:.ctor(System.Management.ManagementOperationObserver,System.Object,System.Management.ManagementScope,System.String,System.String):this
         -28 (-4.06% of base) : System.Net.HttpListener.dasm - System.Net.ServiceNameStore:BuildServiceNames(System.String):System.String[]:this
         -12 (-3.54% of base) : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.VisualBasicCommandLineParser:ParseBaseAddress(System.String,System.String,System.Collections.Generic.List`1[Microsoft.CodeAnalysis.Diagnostic]):long
         -11 (-2.84% of base) : System.Management.dasm - System.Management.SinkForEventQuery:.ctor(System.Management.ManagementEventWatcher,System.Object,System.Management.IWbemServices):this
         -80 (-2.49% of base) : System.Net.Http.dasm - <GetDigestTokenForCredential>d__40:MoveNext():this
        -429 (-2.33% of base) : System.Management.dasm - System.Management.ManagementClassGenerator:GenerateMethods():this
          -3 (-1.71% of base) : System.Management.dasm - System.Management.ManagementPath:SetWbemPath(System.Management.IWbemPath,System.String)
          -6 (-1.62% of base) : System.ComponentModel.TypeConverter.dasm - System.Drawing.ColorConverterCommon:IntFromString(System.String,System.Globalization.CultureInfo):int
          -6 (-1.62% of base) : System.Drawing.Primitives.dasm - System.Drawing.ColorConverterCommon:IntFromString(System.String,System.Globalization.CultureInfo):int
          -8 (-1.48% of base) : System.ComponentModel.TypeConverter.dasm - System.ComponentModel.BaseNumberConverter:ConvertFrom(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object):System.Object:this

132 total methods with Code Size differences (21 improved, 111 regressed), 254519 unchanged.

132 methods improved, I know that aspnetcore also uses it a lot.

@ghost ghost assigned EgorBo Mar 2, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 2, 2022
@ghost
Copy link

ghost commented Mar 2, 2022

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

This PR adds OrdinalIgnoreCase support to #65288 by injecting x | ToLowerMask operation where ToLowerMask looks like this for e.g for "hi2-O" constant value:

  ConstanValue: [  h ][  i ][  2 ][  - ][  O ]
  ToLowerMask:  [0x20][0x20][ 0x0][ 0x0][0x20]

if the constant value contains at least one non-ASCII char (>127) - we give up on optimizing it.

Codegen example

bool EqualsCoreLib(string s) => 
    s.Equals("System.Private.CoreLib.dll", StringComparison.OrdinalIgnoreCase);

New codegen:

; Method EqualsCoreLib(System.String):bool:this
G_M43376_IG01:
       vzeroupper 
G_M43376_IG02:
       cmp      dword ptr [rdx+8], 26
       jne      SHORT G_M43376_IG04
G_M43376_IG03:
       vmovupd  ymm0, ymmword ptr[rdx+12]
       vpor     ymm0, ymm0, ymmword ptr[reloc @RWD00]  ;; ToLower
       vpxor    ymm0, ymm0, ymmword ptr[reloc @RWD32]
       vmovupd  ymm1, ymmword ptr[rdx+32]
       vpor     ymm1, ymm1, ymmword ptr[reloc @RWD64]  ;; ToLower
       vpxor    ymm1, ymm1, ymmword ptr[reloc @RWD96]
       vpor     ymm0, ymm0, ymm1
       vptest   ymm0, ymm0
       sete     al
       movzx    rax, al
       jmp      SHORT G_M43376_IG05
G_M43376_IG04:
       xor      eax, eax
G_M43376_IG05:
       movzx    rax, al
G_M43376_IG06:
       vzeroupper 
       ret      

RWD00  	dq	0020002000200020h, 0020000000200020h, 0020002000200020h, 0020000000200020h
RWD32  	dq	0074007300790073h, 0070002E006D0065h, 0061007600690072h, 0063002E00650074h
RWD64  	dq	0020002000200020h, 0020002000200000h, 0020002000200020h, 0020002000200000h
RWD96  	dq	0065007400610076h, 0072006F0063002Eh, 00620069006C0065h, 006C006C0064002Eh
; Total bytes of code: 77

Benchmark

using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

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

public class Benchmarks
{
    const StringComparison cmp = StringComparison.OrdinalIgnoreCase;

    [Benchmark]
    [Arguments("https://bing.com")]
    public bool StartsWithBing(string s) => s.StartsWith("https://bing", cmp);

    [Benchmark]
    [Arguments("XMLFILE")]
    public bool StartsWithXml(string s) => s.StartsWith("xml", cmp);

    [Benchmark]
    [Arguments("system.private.corelib.dll")]
    public bool EqualsCoreLib(string s) => s.Equals("System.Private.CoreLib.dll", cmp );
}
Method Toolchain Mean Error StdDev Ratio
StartsWithHttps \Core_Root\corerun.exe 5.7167 ns 0.0496 ns 0.0464 ns 10.47
StartsWithHttps \Core_Root_PR\corerun.exe 0.5459 ns 0.0021 ns 0.0017 ns 1.00
StartsWithXml \Core_Root\corerun.exe 4.9878 ns 0.0099 ns 0.0082 ns 11.58
StartsWithXml \Core_Root_PR\corerun.exe 0.4307 ns 0.0067 ns 0.0052 ns 1.00
EqualsCoreLib \Core_Root\corerun.exe 14.1401 ns 0.1850 ns 0.1544 ns 20.68
EqualsCoreLib \Core_Root_PR\corerun.exe 0.6825 ns 0.0238 ns 0.0211 ns 1.00

10-20x faster for these cases.

#65288 added tests which also cover OrdinalIgnoreCase but I might add more.

Author: EgorBo
Assignees: EgorBo
Labels:

area-CodeGen-coreclr

Milestone: -

@EgorBo
Copy link
Member Author

EgorBo commented Mar 6, 2022

cc @dotnet/jit-contrib @AndyAyersMS


// We can use e.g. UINT here to support SIMD for 32bit as well,
// but it significantly complicates code, so 32bit support is left up-for-grabs
assert(sizeof(ssize_t) == 8);
Copy link
Contributor

Choose a reason for hiding this comment

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

You could use static_assert(...) here, so the code would never be enabled.

Copy link
Member Author

Choose a reason for hiding this comment

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

good idea, will change in a follow up PR

vec1 = gtNewSimdBinOpNode(GT_OR, simdType, vec1, toLowerVec1, baseType, simdSize, false);
vec2 = gtNewSimdBinOpNode(GT_OR, simdType, vec2, toLowerVec2, baseType, simdSize, false);
}

// ((v1 ^ cns1) | (v2 ^ cns2)) == zero
GenTree* xor1 = gtNewSimdBinOpNode(GT_XOR, simdType, vec1, cnsVec1, baseType, simdSize, false);
GenTree* xor2 = gtNewSimdBinOpNode(GT_XOR, simdType, vec2, cnsVec2, baseType, simdSize, false);
GenTree* orr = gtNewSimdBinOpNode(GT_OR, simdType, xor1, xor2, baseType, simdSize, false);
return gtNewSimdHWIntrinsicNode(TYP_BOOL, useSingleVector ? xor1 : orr, zero, niEquals, baseType, simdSize);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens when useSingleVector is true. xor2 and orr trees are just abandoned?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, but I assume it's a rare case, basically, 6.25% probability 😄 I was not sure it was worth it to add more control flow here or DEBUG_DESTROY

@EgorBo EgorBo merged commit 78e840e into dotnet:main Mar 9, 2022
@dotnet dotnet locked as resolved and limited conversation to collaborators Apr 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants