У меня есть служба WCF, которая использует LINQ to SQL для своего уровня данных. Используются только хранимые процедуры, нет доступа к динамической таблице. Когда я нацеливаюсь на x64, я получаю половину производительности сборки x86. Я проследил путь до Reflection.Emit.DynamicMethod.CreateDelegate
. Я создал простой тестовый проект, чтобы продемонстрировать разницу в производительности между двумя платформами.Почему DynamicMethod намного медленнее на x64?
Каково конкретное объяснение того, что DynamicMethod является настолько медленнее на x64? Мое смутное понимание заключается в том, что в x64 может быть добавлен дополнительный кусок, участвующий в DynamicInvoke
.
Вот результаты, когда выполняется на Windows, 7 Enterprise x64, Core i7 Q720 @ 1,60 ГГц, однопоточный:
Build Target Average milliseconds to execute 100,000 iterations
x86 5504
x64 14699
Any CPU 14789
И тестовый код:
class Program
{
private delegate string XInvoker(string arg);
private const int OUTER_ITERATIONS = 4;
private const int INNER_ITERATIONS = 100000;
static void Main(string[] args)
{
Console.WriteLine("Timing {0} iterations, repeat {1} times...", INNER_ITERATIONS, OUTER_ITERATIONS);
var watch = new Stopwatch();
long totalMs = 0;
for (int outer = 0; outer < OUTER_ITERATIONS; outer++)
{
watch.Restart();
for (int inner = 0; inner < INNER_ITERATIONS; inner++)
{
var method = new DynamicMethod("X", typeof(string), new[] { typeof(string) });
var ilGen = method.GetILGenerator();
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Ret);
var del = method.CreateDelegate(typeof(XInvoker));
var blah = del.DynamicInvoke("blah");
}
watch.Stop();
totalMs += watch.ElapsedMilliseconds;
Console.WriteLine("Took {0} ms to iterate {1} times", watch.ElapsedMilliseconds, INNER_ITERATIONS);
}
Console.WriteLine();
Console.WriteLine("Overall average: {0} ms to iterate {1} times", totalMs/OUTER_ITERATIONS, INNER_ITERATIONS);
}
}
Как правило, ваш CreateDelegate не будет во внутреннем цикле, правда? – antlersoft
Это эффективно во внутреннем цикле, когда я выполняю нагрузочное тестирование службы WCF. –
@AidanRyan, Можете ли вы попытаться назвать свой метод Main более одного раза? (переименуйте Main на Main2 и напишите новое Main Main Main2 в цикле). –