アプリケーションのプロファイリング中に、パターン マッチの関数チェックが非常に遅いことがわかりました。LINQ を使用して記述されています。この LINQ 式をループに単純に置き換えるだけで、大きな違いが生まれます。それは何ですか?LINQ は本当に悪いことで動作が遅いのでしょうか、それとも何か誤解しているのでしょうか?
private static bool PatternMatch1(byte[] buffer, int position, string pattern)
{
int i = 0;
foreach (char c in pattern)
{
if (buffer[position + i++] != c)
{
return false;
}
}
return true;
}
LINQ を使用したバージョン 2 (Resharper が推奨)
private static bool PatternMatch2(byte[] buffer, int position, string pattern)
{
int i = 0;
return pattern.All(c => buffer[position + i++] == c);
}
LINQ を使用したバージョン 3
private static bool PatternMatch3(byte[] buffer, int position, string pattern)
{
return !pattern.Where((t, i) => buffer[position + i] != t).Any();
}
ラムダを使用したバージョン 4
private static bool PatternMatch4(byte[] buffer, int position, string pattern, Func<char, byte, bool> predicate)
{
int i = 0;
foreach (char c in pattern)
{
if (predicate(c, buffer[position + i++]))
{
return false;
}
}
return true;
}
これが大きなバッファでの使用法です
const int SIZE = 1024 * 1024 * 50;
byte[] buffer = new byte[SIZE];
for (int i = 0; i < SIZE - 3; ++i)
{
if (PatternMatch1(buffer, i, "xxx"))
{
Console.WriteLine(i);
}
}
PatternMatch2
orの呼び出しPatternMatch3
は非常に遅いです。は約 8 秒、 はPatternMatch3
約 4 秒かかりますがPatternMatch2
、呼び出しPatternMatch1
には約 0.6 秒かかります。私が理解している限り、それは同じコードであり、違いはありません。何か案は?