秒表根据代码所在的位置给出不同的结果

时间:2015-05-04 13:24:49

标签: c# c++ c#-4.0

我在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 ++代码的包装器,最终使用字节数组。 我也正在使用"不安全"编译器标志。不确定这是否会产生任何影响。 所有代码都在发布模式下编译。

1 个答案:

答案 0 :(得分:2)

我发现了这个原因。之所以会发生这种情况,是因为在第一种情况下,计算器对象的创建包含在计时结果中,而在第三种情况下则没有。

如果我理解正确的话, 堆栈变量实际上并不是在您键入的行上创建的,而是编译器将内存分配移动到方法" prolog"。

请参阅此页:https://msdn.microsoft.com/en-us/library/tawsa7cb.aspx

"如果需要,prolog将参数寄存器保存在其归属地址中,在堆栈上推送非易失性寄存器,为本地和临时数据分配堆栈的固定部分,并可选择建立一个帧。指针"

所以我的"案例1"包括"新" (因为它发生在TestFunction的序言中)和"案例3"排除它,因为"新"已经发生了。