Это некоторый микро-бенчмаркинг для кода, который проходит через gazillion раз в наносекунду и должен быть быстрым.
Ниже приведен фрагмент кода, сравнивающий
-
x.EndsWith(y, InvariantCulture)
-
Regex(y, Compiled | CultureInvariant).IsMatch(x)
Я получаю следующие цифры:
=============================
Regex : 00:00:01.2235890. Ignore this: 16666666
EndsWith: 00:00:03.2194626. Ignore this: 16666666
=============================
Regex : 00:00:01.0979105. Ignore this: 16666666
EndsWith: 00:00:03.2346031. Ignore this: 16666666
=============================
Regex : 00:00:01.0687845. Ignore this: 16666666
EndsWith: 00:00:03.3199213. Ignore this: 16666666
Другими словами, EndsWith
требуется в 3 раза больше времени Regex
.
Я должен отметить, что я экспериментировал с другими значениями и в зависимости от используемых строковых значений, иногда EndsWith
быстрее, иногда Regex
-.
EndsWith(x, InvariantCulture)
сводится к некоторой проверке аргументов, а затем extern int nativeCompareOrdinalEx(String, int, String, int, int)
, которую я ожидаю быть быстрымудаp > . (Как правильно указал @nhahtdh, в случае InvariantCulture
он вызывает CultureInfo.InvariantCulture.CompareInfo.IsSuffix which calls InternalFindNLSStringEx
. Я случайно следил за тропом Ordinal
)
NB: я только узнал, что при вызове EndsWith с Ordinal
вместо InvariantCulture
EndsWith получает намного быстрее, чем Regex... К сожалению, нет RegexOptions.Ordinal
для сравнения с.
Я также ожидал, что скомпилированное регулярное выражение будет быстрым, но как он может превзойти специализированный метод?
Le code:
string[] BunchOfIDs =
{
"[email protected]@[email protected]@abcße",
"[email protected]@[email protected]@abcßX",
"[email protected]@[email protected]@abcße",
"[email protected]@[email protected]",
"[email protected]@[email protected]@aXcße",
"[email protected]@[email protected]@aYcße",
};
var endsWith = "@abcße";
var endsWithRegex = new Regex("@abcße$", RegexOptions.None);
int reps = 20000000;
for (int i = 0; i < 3; i++)
{
Console.WriteLine("=============================");
int x = 0;
var sw = Stopwatch.StartNew();
for (int j = 0; j < reps; j++)
{
x += BunchOfIDs[j % BunchOfIDs.Length].EndsWith(endsWith, StringComparison.InvariantCulture) ? 1 : 2;
}
Console.WriteLine("EndsWith: " + sw.Elapsed + ". Ignore this: " + x);
x = 0;
sw = Stopwatch.StartNew();
for (int j = 0; j < reps; j++)
{
x += endsWithRegex.IsMatch(BunchOfIDs[j % BunchOfIDs.Length]) ? 1 : 2;
}
Console.WriteLine("Regex : " + sw.Elapsed + ". Ignore this: " + x);
}