我试图找到运行函数所花费的时间。我是这样做的:
SomeFunc(input) {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//some operation on input
stopWatch.Stop();
long timeTaken = stopWatch.ElapsedMilliseconds;
}
现在,评论中提到的“输入上的某些操作”会根据SomeFunc
的输入占用大量时间。
问题是当我从主要时间多次调用SomeFunc
时,我只是第一次正确得到时间,其余的时间被分配给0.上面是否有问题码?
修改 有一个包含多个文本字段的UI,当单击一个按钮时,它被委托给SomeFunc。 SomeFunc根据输入(来自文本字段)进行一些计算,并在UI上显示结果。自从我签署了NDA以来,我不允许在“输入操作”中共享代码。然而,我可以回答你关于我想在那里实现的问题。请帮忙。
编辑2: 因为看起来第一次调用函数时我得到了奇怪的值,并且正如@Mike Bantegui所提到的那样,必须进行JIT优化,这是我现在能想到的唯一解决方案(执行时间不会为零)是以纳秒为单位显示时间。如何在C#中以纳秒为单位显示时间?
答案 0 :(得分:2)
事实上,你在第一次开始时得到的时间错误,剩下的时间也正确。 您不能仅在第一次通话中继来测量时间。然而,它接近操作太快,因此您得到0
结果。要正确测量测试,请调用该函数1000次,例如查看平均成本时间:
Stopwatch watch = StopWatch.StartNew();
for (int index = 0; index < 1000; index++)
{
SomeFunc(input);
}
watch.Stop();
Console.WriteLine(watch.ElapsedMilliseconds);
修改强>
如何以纳秒为单位显示时间
您可以获得watch.ElapsedTicks
,然后将其转换为纳秒:(watch.ElapsedTicks / Stopwatch.Frequency) * 1000000000
答案 1 :(得分:2)
嗯,你不是在任何地方输出数据。理想情况下,你会做更像这样的事情。
void SomeFunc(input)
{
Do sstuff
}
main()
{
List<long> results = new List<long>();
Stopwatch sw = new Stopwatch();
for(int i = 0; i < MAX_TRIES; i++)
{
sw.Start();
SomeFunc(arg);
sw.Stop();
results.Add(sw.ElapsedMilliseconds);
sw.Reset();
}
//Perform analyses and results
}
答案 2 :(得分:1)
作为一个简单的例子,请考虑以下(人为的)示例:
double Mean(List<double> items)
{
double mu = 0;
foreach (double val in items)
mu += val;
return mu / items.Length;
}
我们可以这样计时:
void DoTimings(int n)
{
Stopwatch sw = new Stopwatch();
int time = 0;
double dummy = 0;
for (int i = 0; i < n; i++)
{
List<double> items = new List<double>();
// populate items with random numbers, excluded for brevity
sw.Start();
dummy += Mean(items);
sw.Stop();
time += sw.ElapsedMilliseconds;
}
Console.WriteLine(dummy);
Console.WriteLine(time / n);
}
如果项目列表实际上非常大,则此方法有效。但如果它太小,我们将不得不在一个时间内进行多次运行:
void DoTimings(int n)
{
Stopwatch sw = new Stopwatch();
int time = 0;
double dummy = 0;
List<double> items = new List<double>(); // Reuse same list
// populate items with random numbers, excluded for brevity
sw.Start();
for (int i = 0; i < n; i++)
{
dummy += Mean(items);
time += sw.ElapsedMilliseconds;
}
sw.Stop();
Console.WriteLine(dummy);
Console.WriteLine(time / n);
}
在第二个示例中,如果列表的大小太小,那么我们可以通过简单地运行足够大的n
来准确地了解所需的时间。每个人都有它的优点和缺点。
然而,在做其中任何一项之前,我会先做一个“热身”计算:
// Or something smaller, just enough to let the compiler JIT
double dummy = 0;
for (int i = 0; i < 10000; i++)
dummy += Mean(data);
Console.WriteLine(dummy);
// Now do the actual timing
两者的另一种方法是执行@Rig在答案中所做的事情,并建立一个结果列表来进行统计。在第一种情况下,您只需构建每个单独时间的列表。在第二种情况下,您将建立一个多次运行的平均时间列表,因为计算的时间可能小于秒表中最精细的时间。
尽管如此,我要说的是,所有这一切都有一个非常大的警告:计算运行某些东西所需的时间很难正确完成。想要进行性能分析是令人钦佩的,但是你应该对SO进行一些研究,看看其他人做了什么才能做到这一点。编写一个时间错误的例行程序非常容易,但很难做到这一点。