- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
对不起,它很长,但我只是在分析这个时解释我的思路。问题在最后。
我了解测量代码运行时间的内容。它运行多次以获得平均运行时间,以解释每次运行的差异,并获得更好地利用缓存的时间。
为了测量某人的运行时间,我想出了 this多次修改后的代码。
最后我得到了这段代码,它产生了我打算捕获的结果,而不会给出误导性的数字:
// implementation C
static void Test<T>(string testName, Func<T> test, int iterations = 1000000)
{
Console.WriteLine(testName);
Console.WriteLine("Iterations: {0}", iterations);
var results = Enumerable.Repeat(0, iterations).Select(i => new System.Diagnostics.Stopwatch()).ToList();
var timer = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < results.Count; i++)
{
results[i].Start();
test();
results[i].Stop();
}
timer.Stop();
Console.WriteLine("Time(ms): {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedMilliseconds), results.Average(t => t.ElapsedMilliseconds), results.Max(t => t.ElapsedMilliseconds), timer.ElapsedMilliseconds);
Console.WriteLine("Ticks: {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedTicks), results.Average(t => t.ElapsedTicks), results.Max(t => t.ElapsedTicks), timer.ElapsedTicks);
Console.WriteLine();
}
// approach 1 pseudocodestart timer;loop N times: run testing code (directly or via function);stop timer;report results;
This was good in my mind since with the numbers, I have the total running time and can easily work out the average running time and would have good cache locality.
But one set of values that I thought were important to have were minimum and maximum iteration running time. This could not be calculated using the above form. So when I wrote my testing code, I wrote them in this form:
// approach 2 pseudocodeloop N times: start timer; run testing code (directly or via function); stop timer; store results;report results;
This is good because I could then find the minimum, maximum as well as average times, the numbers I was interested in. Until now I realized that this could potentially skew results since the cache could potentially be affected since the loop wasn't very tight giving me less than optimal results.
The way I wrote the test code (using LINQ) added additional overheads which I knew about but ignored since I was just measuring the running code, not the overheads. Here was my first version:
// implementation A
static void Test<T>(string testName, Func<T> test, int iterations = 1000000)
{
Console.WriteLine(testName);
var results = Enumerable.Repeat(0, iterations).Select(i =>
{
var timer = System.Diagnostics.Stopwatch.StartNew();
test();
timer.Stop();
return timer;
}).ToList();
Console.WriteLine("Time(ms): {0,3}/{1,10}/{2,8}", results.Min(t => t.ElapsedMilliseconds), results.Average(t => t.ElapsedMilliseconds), results.Max(t => t.ElapsedMilliseconds));
Console.WriteLine("Ticks: {0,3}/{1,10}/{2,8}", results.Min(t => t.ElapsedTicks), results.Average(t => t.ElapsedTicks), results.Max(t => t.ElapsedTicks));
Console.WriteLine();
}
// implementation B
static void Test<T>(string testName, Func<T> test, int iterations = 1000000)
{
Console.WriteLine(testName);
Console.WriteLine("Iterations: {0}", iterations);
var results = Enumerable.Repeat(0, iterations).Select(i => new System.Diagnostics.Stopwatch()).ToList();
results.ForEach(t =>
{
t.Start();
test();
t.Stop();
});
Console.WriteLine("Time(ms): {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedMilliseconds), results.Average(t => t.ElapsedMilliseconds), results.Max(t => t.ElapsedMilliseconds), results.Sum(t => t.ElapsedMilliseconds));
Console.WriteLine("Ticks: {0,3}/{1,10}/{2,8} ({3,10})", results.Min(t => t.ElapsedTicks), results.Average(t => t.ElapsedTicks), results.Max(t => t.ElapsedTicks), results.Sum(t => t.ElapsedTicks));
Console.WriteLine();
}
// final implementation
static void Test<T>(string testName, Func<T> test, int iterations = 1000000)
{
// print header
var results = Enumerable.Repeat(0, iterations).Select(i => new System.Diagnostics.Stopwatch()).ToList();
for (int i = 0; i < 100; i++) // warm up the cache
{
test();
}
var timer = System.Diagnostics.Stopwatch.StartNew(); // time whole process
for (int i = 0; i < results.Count; i++)
{
results[i].Start(); // time individual process
test();
results[i].Stop();
}
timer.Stop();
// report results
}
Thread.Yield()
在循环中帮助还是损害了 CPU 绑定(bind)测试用例的时间? 最佳答案
我的第一个想法是一个简单的循环
for (int i = 0; i < x; i++)
{
timer.Start();
test();
timer.Stop();
}
timer.Start();
for (int i = 0; i < x; i++)
test();
timer.Stop();
// A lightweight class to help you compute the minimum, maximum, average
// and standard deviation of a set of values. Call Clear(), then Add(each
// value); you can compute the average and standard deviation at any time by
// calling Avg() and StdDeviation().
class Statistic
{
public double Min;
public double Max;
public double Count;
public double SumTotal;
public double SumOfSquares;
public void Clear()
{
SumOfSquares = Min = Max = Count = SumTotal = 0;
}
public void Add(double nextValue)
{
Debug.Assert(!double.IsNaN(nextValue));
if (Count > 0)
{
if (Min > nextValue)
Min = nextValue;
if (Max < nextValue)
Max = nextValue;
SumTotal += nextValue;
SumOfSquares += nextValue * nextValue;
Count++;
}
else
{
Min = Max = SumTotal = nextValue;
SumOfSquares = nextValue * nextValue;
Count = 1;
}
}
public double Avg()
{
return SumTotal / Count;
}
public double Variance()
{
return (SumOfSquares * Count - SumTotal * SumTotal) / (Count * (Count - 1));
}
public double StdDeviation()
{
return Math.Sqrt(Variance());
}
public Statistic Clone()
{
return (Statistic)MemberwiseClone();
}
};
关于c# - 我测量运行时间的方法有缺陷吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4001610/
我想捕捉发送到我的窗口的按键以存储每个键的状态,并区分键的左右实例,如 WM_LCONTROL 和 WM_RCONTROL. 因为 WM_KEYUP/DOWN 不提供此功能,所以我转向原始输入,我需要
我有以下代码: Area here jQuery: $('#area').on('mouseenter', function(event){ $('#area').addC
这个问题在这里已经有了答案: Why does a RegExp with global flag give wrong results? (7 个答案) 关闭 7 个月前。 我向你保证我没有说谎。
我想知道以下问题的答案。 1) 如果我尝试使用 AVAudioSession 播放音频,而 iphone 扬声器有故障/有缺陷/不工作,会发生什么情况? 2) 有什么方法可以通过程序检查扬声器是正常工
我是一名优秀的程序员,十分优秀!