Как объяснено в этой статье MSDN , при использовании .NET Reflection API, такого как InvokeMember
, первый вызов выполняется намного больше времени, чем последующие вызовы из-за кэширования метаданных.
Когда я тестировал прямой вызов метода без использования Reflection, я также вижу похожий эффект как в Mono, так и в .NET 4.
Первое число является результатом операции, а второе число после «-» - это время, затраченное на эту операцию в мс. Я использовал знак «<-» для идентификации первого вызова метода. </p>
300 - 0.192 <--
300 - 0.004
300 - 0.004
-100 - 0.096 <--
-100 - 0.004
-100 - 0.004
Почему это? Я понимаю, что первый вызов может быть медленнее, но в 50 раз медленнее, чем я ожидал.
Прилагается исходный код для получения этого результата.
библиотека
namespace MyClass
{
public class Calculator
{
public int Value1 {get; set;}
public int Value2 {get; set;}
public Calculator()
{
Value1 = 100;
Value2 = 200;
}
public int Add(int val1, int val2)
{
Value1 = val1; Value2 = val2;
return Value1 + Value2;
}
public int Sub(int val1, int val2)
{
Value1 = val1; Value2 = val2;
return Value1 - Value2;
}
}
}
Код для вызова этой библиотеки
// http://msdn.microsoft.com/en-us/magazine/cc163759.aspx
using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;
using MyClass;
class TestOne
{
static void DirectTest()
{
Stopwatch sw;
Calculator t = new Calculator();
sw = Stopwatch.StartNew();
int value1 = t.Add(100,200);
sw.Stop();
double time1 = sw.Elapsed.TotalMilliseconds;
sw = Stopwatch.StartNew();
int value2 = t.Add(100,200);
sw.Stop();
double time2 = sw.Elapsed.TotalMilliseconds;
sw = Stopwatch.StartNew();
int value3 = t.Add(100,200);
sw.Stop();
double time3 = sw.Elapsed.TotalMilliseconds;
Console.WriteLine("{0} - {1}", value1, time1);
Console.WriteLine("{0} - {1}", value2, time2);
Console.WriteLine("{0} - {1}", value3, time3);
sw = Stopwatch.StartNew();
value1 = t.Sub(100,200);
sw.Stop();
time1 = sw.Elapsed.TotalMilliseconds;
sw = Stopwatch.StartNew();
value2 = t.Sub(100,200);
sw.Stop();
time2 = sw.Elapsed.TotalMilliseconds;
sw = Stopwatch.StartNew();
value3 = t.Sub(100,200);
sw.Stop();
time3 = sw.Elapsed.TotalMilliseconds;
Console.WriteLine("{0} - {1}", value1, time1);
Console.WriteLine("{0} - {1}", value2, time2);
Console.WriteLine("{0} - {1}", value3, time3);
}
static void Main()
{
DirectTest();
DirectTest();
}
}