summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2016-01-14 20:59:15 -0500
committerStephen Toub <stoub@microsoft.com>2016-01-14 20:59:15 -0500
commitf06fa2ea19a57631d7bac1fad232888a2c039a9b (patch)
tree097cd3a23d3964e45b3490583e45054dc1ff143d /src
parentdbc957173de0582162f2a2488bf6b7dba6726345 (diff)
parent8c82dd5428bdab80ce2f1a0803747c2406b9f178 (diff)
downloadcoreclr-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.cs43
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;
+ }
}
}