5

我有一个while循环,它所做的只是一个方法调用。我在循环外部有一个计时器,另一个计时器递增地增加方法调用在循环内花费的时间。外部时间大约需要 17 秒,内部计时器的总时间为 40 毫秒。该循环正在执行 50,000 次。以下是代码示例:

long InnerTime = 0;
long OutterTime = 0;
Stopw1.Start();
int count = 1;
while (count <= TestCollection.Count) {
    Stopw2.Start();
    Medthod1();
    Stopw2.Stop();
    InnerTime = InnerTime + Stopw2.ElapsedMilliseconds;
    Stopw2.Reset();
    count++;
}
Stopw1.Stop();
OutterTime = Stopw1.ElapsedMilliseconds;
Stopw1.Reset();

任何帮助将非常感激。马西莫

4

6 回答 6

8

你在比较苹果和橘子。您的外部计时器测量所用的总时间。您的内部计时器测量调用Method1.

ElapsedMilliseconds属性“表示向下舍入到最接近的整数毫秒值的经过时间” 。因此,您将四舍五入最接近的毫秒约 50,000 次。

如果您的调用Method1平均不到 1 毫秒,那么大多数情况下,“ElapsedMilliseconds”属性将返回 0,您的内部计数将比实际时间少得多。事实上,你的方法平均需要大约 0.3 毫秒,所以你很幸运,甚至可以让它超过 1 毫秒 40 次。

使用Elapsed.TotalMillisecondsorElapsedTicks属性代替ElapsedMilliseconds. 一毫秒相当于 10,000 个滴答声。

于 2012-07-19T17:45:11.323 回答
2

这是在做什么:TestCollection.Count

我怀疑你的 17 秒是在一遍又一遍地计算你的 50,000 件物品上。

于 2012-07-19T17:29:58.067 回答
1

尝试改变这个:

while (count <= TestCollection.Count) {
...
}

对此:

int total = TestCollection.Count;
while (count <= total) {
...
}
于 2012-07-19T17:33:04.517 回答
1

为了补充其他人已经说过的内容,通常 C# 编译器必须重新评估任何属性,包括

TestCollection.Count

对于每一个循环迭代。属性的值可能会随着迭代而变化。

将值分配给局部变量可以消除编译器对每次循环迭代重新评估的需要。

我知道的一个例外是 Array.Length,它受益于专门针对数组的优化。这称为Array Bounds Check Elimination

于 2012-07-19T17:37:55.063 回答
0

要正确测量通话时间,您应该使用刻度

请尝试以下方法:

long InnerTime = 0;
long OutterTime = 0;

Stopwatch Stopw1 = new Stopwatch();
Stopwatch Stopw2 = new Stopwatch();

Stopw1.Start();
int count = 1;
int run = TestCollection.Count;
while (count <= run) {
    Stopw2.Start();
    Medthod1();
    Stopw2.Stop();
    InnerTime = InnerTime + Stopw2.ElapsedTicks;
    Stopw2.Reset();
    count++;
}
Stopw1.Stop();
OutterTime = Stopw1.ElapsedTicks;
Stopw1.Reset();
于 2012-07-19T17:51:50.663 回答
0

您不应该单独测量这种微小的方法。但如果你真的想,试试这个:

long innertime = 0;

while (count <= TestCollection.Count) 
{     
    innertime -= Stopw2.GetTimestamp();
    Medthod1();
    innertime += Stopw2.GetTimestamp();
    count++; 
} 

Console.WriteLine("{0} ms", innertime * 1000.0 / Stopw2.Frequency);
于 2012-07-19T17:57:33.487 回答