While profiling applications, I found that checking the function for pattern matching is very slow. It is written using LINQ. Simply replacing this LINQ expression with a loop makes a huge difference. What is it? Is LINQ really such a bad thing and it works so slowly, or am I misunderstanding something?
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; }
version 2 with LINQ (proposed by Resharper)
private static bool PatternMatch2(byte[] buffer, int position, string pattern) { int i = 0; return pattern.All(c => buffer[position + i++] == c); }
version 3 with LINQ
private static bool PatternMatch3(byte[] buffer, int position, string pattern) { return !pattern.Where((t, i) => buffer[position + i] != t).Any(); }
version 4 using lambda
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; }
and used here with a large buffer
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); } }
Calling PatternMatch2 or PatternMatch3 phenomenally slow. This takes about 8 seconds for PatternMatch3 and about 4 seconds for PatternMatch2 , and when you call PatternMatch1 , about 0.6. As far as I understand, this is the same code, and I see no difference. Any ideas?