Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C中的慢While循环#_C#_Performance_Loops_While Loop - Fatal编程技术网

C# C中的慢While循环#

C# C中的慢While循环#,c#,performance,loops,while-loop,C#,Performance,Loops,While Loop,我有一个while循环,它所做的只是一个方法调用。我在循环外部有一个计时器,另一个计时器递增地将方法调用在循环内部花费的时间相加。外部时间约为17秒,内部计时器的总时间为40毫秒。循环执行50000次。下面是一个代码示例: long InnerTime = 0; long OutterTime = 0; Stopw1.Start(); int count = 1; while (count <= TestCollection.Count) { Stopw2.Start();

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

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();
long InnerTime=0;
长超时=0;
Stopw1.Start();
整数计数=1;

while(count这是做什么的:
TestCollection.count

我怀疑你花了17秒的时间一遍又一遍地数着你的50000件物品。

试着改变一下:

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

while(count要补充其他人已经说过的内容,通常C#编译器必须重新计算任何属性,包括

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

将该值赋给局部变量可以消除编译器对每次循环迭代重新求值的需要


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

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

属性“表示经过的时间向下舍入到最接近的整毫秒值。”因此,您将向下舍入到最接近的毫秒大约50000次

如果您对
Method1
的调用平均耗时不到1ms,那么在大多数情况下,`elapsedmillseconds'属性将返回0,并且您的内部计数将远小于实际时间。事实上,您的方法平均耗时约0.3ms,因此,您很幸运地使其超过1ms 40次


使用
eaperd.totalmillimess
ElapsedTicks
属性,而不是
ElapsedMilliseconds
。一毫秒相当于10000个滴答声。

要正确测量通话时间, 你应该使用滴答声

请尝试以下操作:

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();
long InnerTime=0;
长超时=0;
秒表Stopw1=新秒表();
秒表Stopw2=新秒表();
Stopw1.Start();
整数计数=1;
int run=TestCollection.Count;

while(count您不应该单独测量这样一个微小的方法。但是如果您真的想,请尝试以下方法:

long innertime = 0;

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

Console.WriteLine("{0} ms", innertime * 1000.0 / Stopw2.Frequency);
long innertime=0;

while(count)您是否尝试过删除内环计时代码并查看它是否加快了速度?代码似乎很好,除了“Method1”,我们不知道它是做什么的。否则,关于计时器似乎一切正常!什么是
TestCollection
-它是一个方法、一个变量/属性还是什么?试着用一个常量替换
TestCollection.Count
(显然是一个足够低的常量)。尝试执行
int countLimit=TestCollection.Count
循环之外的操作,并在您的条件下使用countLimit。如果集合是高度动态的,这可能是一个非常昂贵的评估。如果TestCollection是集合或列表的实例,则Count是O(1)操作。除非它是某种低效的自定义类,否则它不应该导致问题。你认为它正在计算50000次的能力吗?有趣的是,
TestCollection
的类型是什么。你可能正在考虑Linq
Count()
表达式而不是
ICollection.Count
property.ICollection.Count通常只返回一个私有字段值。虽然该值可能会更改并引起问题,但我不认为“重新评估属性”是问题所在。当然,我认为真正的问题是他没有像@Jeffrey指出的那样正确测量。只是在r完整性。有时相对于循环体,属性评估是昂贵的(只是不在这里)。使用ElapsedTicks可以更准确地反映时间。结果证明只有72毫秒的时差。谢谢Jeffrey
long innertime = 0;

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

Console.WriteLine("{0} ms", innertime * 1000.0 / Stopw2.Frequency);