diff options
author | Stephen Toub <stoub@microsoft.com> | 2016-01-14 20:59:15 -0500 |
---|---|---|
committer | Stephen Toub <stoub@microsoft.com> | 2016-01-14 20:59:15 -0500 |
commit | f06fa2ea19a57631d7bac1fad232888a2c039a9b (patch) | |
tree | 097cd3a23d3964e45b3490583e45054dc1ff143d /src | |
parent | dbc957173de0582162f2a2488bf6b7dba6726345 (diff) | |
parent | 8c82dd5428bdab80ce2f1a0803747c2406b9f178 (diff) | |
download | coreclr-f06fa2ea19a57631d7bac1fad232888a2c039a9b.tar.gz coreclr-f06fa2ea19a57631d7bac1fad232888a2c039a9b.tar.bz2 coreclr-f06fa2ea19a57631d7bac1fad232888a2c039a9b.zip |
Merge pull request #2630 from ellismg/fast-path-index-of
Fast path IndexOf and variants for ASCII
Diffstat (limited to 'src')
-rw-r--r-- | src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs index 905ac9deb2..2337fed15c 100644 --- a/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs +++ b/src/mscorlib/corefx/System/Globalization/CompareInfo.Unix.cs @@ -13,12 +13,15 @@ namespace System.Globalization [SecurityCritical] private readonly Interop.GlobalizationInterop.SafeSortHandle m_sortHandle; + private readonly bool m_isAsciiEqualityOrdinal; + [SecuritySafeCritical] internal CompareInfo(CultureInfo culture) { m_name = culture.m_name; m_sortName = culture.SortName; m_sortHandle = Interop.GlobalizationInterop.GetSortHandle(System.Text.Encoding.UTF8.GetBytes(m_sortName)); + m_isAsciiEqualityOrdinal = (m_sortName == "en-US" || m_sortName == ""); } [SecurityCritical] @@ -161,6 +164,11 @@ namespace System.Globalization return IndexOfOrdinal(source, target, startIndex, count, ignoreCase: false); } + if (m_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsAscii() && target.IsAscii()) + { + return IndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options)); + } + fixed (char* pSource = source) { int index = Interop.GlobalizationInterop.IndexOf(m_sortHandle, target, target.Length, pSource + startIndex, count, options); @@ -180,12 +188,17 @@ namespace System.Globalization { return startIndex; } - + if (options == CompareOptions.Ordinal) { return LastIndexOfOrdinal(source, target, startIndex, count, ignoreCase: false); } + if (m_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsAscii() && target.IsAscii()) + { + return LastIndexOf(source, target, startIndex, count, GetOrdinalCompareOptions(options)); + } + // startIndex is the index into source where we start search backwards from. leftStartIndex is the index into source // of the start of the string that is count characters away from startIndex. int leftStartIndex = (startIndex - count + 1); @@ -205,6 +218,11 @@ namespace System.Globalization Contract.Assert(!string.IsNullOrEmpty(prefix)); Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + if (m_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsAscii() && prefix.IsAscii()) + { + return IsPrefix(source, prefix, GetOrdinalCompareOptions(options)); + } + return Interop.GlobalizationInterop.StartsWith(m_sortHandle, prefix, prefix.Length, source, source.Length, options); } @@ -215,6 +233,11 @@ namespace System.Globalization Contract.Assert(!string.IsNullOrEmpty(suffix)); Contract.Assert((options & (CompareOptions.Ordinal | CompareOptions.OrdinalIgnoreCase)) == 0); + if (m_isAsciiEqualityOrdinal && CanUseAsciiOrdinalForOptions(options) && source.IsAscii() && suffix.IsAscii()) + { + return IsSuffix(source, suffix, GetOrdinalCompareOptions(options)); + } + return Interop.GlobalizationInterop.EndsWith(m_sortHandle, suffix, suffix.Length, source, source.Length, options); } @@ -251,5 +274,23 @@ namespace System.Globalization [DllImport(JitHelpers.QCall)] [SuppressUnmanagedCodeSecurity] private static unsafe extern int InternalHashSortKey(byte* sortKey, int sortKeyLength, [MarshalAs(UnmanagedType.Bool)] bool forceRandomizedHashing, long additionalEntropy); + + private static CompareOptions GetOrdinalCompareOptions(CompareOptions options) + { + if ((options & CompareOptions.IgnoreCase) == CompareOptions.IgnoreCase) + { + return CompareOptions.OrdinalIgnoreCase; + } + else + { + return CompareOptions.Ordinal; + } + } + + private static bool CanUseAsciiOrdinalForOptions(CompareOptions options) + { + // Unlike the other Ignore options, IgnoreSymbols impacts ASCII characters (e.g. '). + return (options & CompareOptions.IgnoreSymbols) == 0; + } } } |