在C#中循环缓慢

时间:2012-07-19 17:24:34

标签: c# performance loops while-loop

我有一个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();

非常感谢任何帮助。 马西莫

7 个答案:

答案 0 :(得分:8)

您正在比较苹果和橘子。您的外部计时器测量所花费的总时间。您的内部计时器测量调用Method1所花费的整个毫秒数。

ElapsedMilliseconds 属性“表示向下舍入到最接近的整个毫秒值的经过时间。”所以,你将向下四舍五入到最近的毫秒大约50,000次。

如果您对Method1的调用平均小于1毫秒,那么大部分时间,`ElapsedMilliseconds'属性将返回0并且您的内部计数将远远少于实际时间。事实上,你的方法平均需要大约0.3毫秒,所以你很幸运,甚至超过1毫秒40次。

使用Elapsed.TotalMillisecondsElapsedTicks属性代替ElapsedMilliseconds。一毫秒相当于10,000个刻度。

答案 1 :(得分:2)

这是做什么的:TestCollection.Count

我怀疑你花了17秒钟一遍又一遍地计算你的50,000件物品。

答案 2 :(得分:1)

尝试更改此内容:

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

到此:

int total = TestCollection.Count;
while (count <= total) {
...
}

答案 3 :(得分:1)

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

TestCollection.Count

每次循环迭代。属性的值可能会从迭代变为迭代。

将值赋值给局部变量会消除编译器为每次循环迭代重新求值的需要。

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

答案 4 :(得分:0)

要正确测量您的通话时间, 你应该使用Ticks

请尝试以下方法:

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();

答案 5 :(得分: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);

答案 6 :(得分:0)

由于您从int count = 1;开始,如果您的循环执行50,000次,则意味着TestCollection.Count的值为50,000。因此,您的代码需要计算50,000 TestCollection.Count次50,000的值,每次进入循环一次;
因此,根据Medthod1()的确实做什么,花时间可能是正常的。将TestCollection.Count的值存储在变量中,并将循环计数器与该计数器进行比较。