我在C#项目中遇到了一些令人困惑的Stopwatch
结果。请考虑以下代码:
static void Main(string[] args)
{
byte[] myEventArray = GetEventByteArrayFromDatabase();
byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase();
uint numEvents = 1000;
uint numEventItems = 1000;
Stopwatch sw1 = Stopwatch.StartNew();
TestFunction(ref myEventArray, numEvents, ref myEventItemsArray, numEventItems);
sw1.Stop();
float timeTakenInSeconds = (float)sw2.ElapsedTicks / Stopwatch.Frequency;
Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. ");
}
static void TestFunction(ref byte[] EventArray, uint numEvents, ref byte[] EventItemArray, uint numEventItems)
{
Calculator calc = new Calculator();
calc.Test(EventArray, numEvents, EventItemArray, numEventItems);
}
我跑了这个,得到大约0.2秒的时间。 现在考虑一下:
static void Main(string[] args)
{
byte[] myEventArray = GetEventByteArrayFromDatabase();
byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase();
uint numEvents = 1000;
uint numEventItems = 1000;
Stopwatch sw1 = Stopwatch.StartNew();
Calculator calc = new Calculator();
calc.Test(myEventArray , numEvents, myEventItemsArray , numEventItems);
sw1.Stop();
float timeTakenInSeconds = (float)sw1.ElapsedTicks / Stopwatch.Frequency;
Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. ");
}
我运行它,并得到类似的结果,正如人们所期望的那样。 最后,看看这个:
static void Main(string[] args)
{
byte[] myEventArray = GetEventByteArrayFromDatabase();
byte[] myEventItemsArray = GetEventItemByteArrayFromDatabase();
uint numEvents = 1000;
uint numEventItems = 1000;
TestFunction(ref myEventArray, numEvents, ref myEventItemsArray, numEventItems);
}
static void TestFunction(ref byte[] EventArray, uint numEvents, ref byte[] EventItemArray, uint numEventItems)
{
Stopwatch sw1 = Stopwatch.StartNew();
Calculator calc = new Calculator();
calc.Test(EventArray, numEvents, EventItemArray, numEventItems);
sw1.Stop();
float timeTakenInSeconds = (float)sw1.ElapsedTicks / Stopwatch.Frequency;
Console.WriteLine("Total time: " + timeTakenInSeconds + " seconds. ");
}
当我运行那个时,由于某种原因,时间结果始终快十倍。 任何想法为什么会这样?
更多信息: Calculator类在C ++ / CLI中定义。我将它用作本机C ++代码的包装器,最终使用字节数组。 我也正在使用"不安全"编译器标志。不确定这是否会产生任何影响。 所有代码都在发布模式下编译。
答案 0 :(得分:2)
我发现了这个原因。之所以会发生这种情况,是因为在第一种情况下,计算器对象的创建包含在计时结果中,而在第三种情况下则没有。
如果我理解正确的话, 堆栈变量实际上并不是在您键入的行上创建的,而是编译器将内存分配移动到方法" prolog"。
请参阅此页:https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx
"如果需要,prolog将参数寄存器保存在其归属地址中,在堆栈上推送非易失性寄存器,为本地和临时数据分配堆栈的固定部分,并可选择建立一个帧。指针"
所以我的"案例1"包括"新" (因为它发生在TestFunction的序言中)和"案例3"排除它,因为"新"已经发生了。