我们应该在优化代码中信任秒表吗? [英] Should we trust Stopwatch in optimized code?

查看:75
本文介绍了我们应该在优化代码中信任秒表吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为编写各种铸造场景的性能分析基准的一部分,我发现Stopwatch类(& QueryPerformanceCounter)在我的测试场景下提供了(当启用优化时编译)不可预测的结果. 在具有混合对象(int和null)的数组上使用的Sum函数.为了说明我在说什么,我提供以下代码.

As part of writing a benchmark for performance profiling of various casting scenario's, I've found that the Stopwatch class (& QueryPerformanceCounter) provides (when compiled with optimize enabled) unpredictable results under my test scenario of a Sum function used on an array with mixed objects (int and null). To illustrate what I am talking about, I provide the code below.

static void Main()
{
    Object[] TestArray = MakeTestArray(100000000);

    long start = Stopwatch.GetTimestamp();
    int sum = CastAndCalculateSum(TestArray);
    long stop = Stopwatch.GetTimestamp();

    Console.WriteLine(sum + " sum");
    Console.WriteLine((stop - start) + " diff console ticks");
    Console.WriteLine("Stopwatch/QPC is bad"); // Speed Toggle
}

static Object[] MakeTestArray(int arrSize)
{
    Object[] arr = new Object[arrSize];

    for (int i = 0; i < (arr.Length - 2); i = i + 3)
    {
        arr[i] = 1;
        arr[i + 1] = null;
        arr[i + 2] = null;
    }

    return arr;
}

static int CastAndCalculateSum(object[] arr)
{
    int sum = 0;
    foreach (object o in arr)
    {
        if (o is int)
        {
            int x = (int) o;
            sum += x;
        }
    }
    return sum;
}

编译与编辑上面代码的执行(情况X)始终会导致〜335000个滴答的执行时间,而使用Console.WriteLine("Stopwatch/QPC不好")注释(情况Y),它始终会导致〜595000个滴答的执行时间 时间.但是,我的执行脚本证实了案例X和案例Y在整体上的可执行文件执行时间几乎没有区别.使情况如此奇怪的是,为提供控制台输出的行提供了机会(例如) 可以轻松地扭转这种情况(案例X的跳动数比案例Y的要多得多).

Compilation & Execution of the code above (case X) consistently results in ~335000 ticks execution time, whereas with with Console.WriteLine("Stopwatch/QPC is bad") commented (case Y) it consistently results in ~595000 ticks execution time. Yet, my execution-script confirms that there is nearly no difference in the execution time of the executable as a whole between case X and case Y. What makes the situation so odd is that making chances to the lines providing console output (for example) can easily reverse the situation (case X having a much higher number of ticks than case Y).

我尝试了各种编译器/程序集(包括最新的2.0.0.61501/4.6.2),但是根据上述Console.WriteLine是否被注释,会出现相同的X/Y滴答差异.我已经尝试过未成年人&主要代码变更,但仅 发现,每次代码更改(即使在周围换行时)也会导致滴答的执行时间大不相同(案例X和案例Y是四肢).我尝试了不同的秒表方法(例如开始/停止调用),并使用QueryPerformanceCounter 直接,但是又会出现较大的X/Y差,而没有(我)找到可识别的原因.我尝试使用基于文件的输出而不是基于控制台的输出,但是仍然会出现较大的X/Y差异.

I've tried various compilers/Assemblies (including the latest: 2.0.0.61501/4.6.2), but the same large X/Y tick-difference occurs depending on aforementioned Console.WriteLine being commented or not. I've tried minor & major code alternations, but only found that each code alteration (even when swapping lines around) results in widely different ticks execution time (case X & case Y are extremities). I've tried different Stopwatch approaches (e.g. start/stop calling), and using QueryPerformanceCounter directly, but again the large X/Y difference tends to occur without (me) finding an identifiable cause. I've tried using File-based ouput instead of a Console-based one, but yet again the large X/Y difference occurs.

我已经擦完了整个硬盘,重新安装整个操作系统(结果无明显差异),通过用Sleep调用替换CastAndCalculateSum来测试Stopwatch(按预期工作),并确保Frequency和Stopwatch. 在操作过程中保持不变.

I've gone as far as wiping my entire drive & re-installing the entire OS (resulted in no noticeable differences), testing Stopwatch by replacing CastAndCalculateSum with a Sleep call (works as expected), and ensuring the Frequency and Stopwatch.IsHighResolution remain the same during operation.

所以我对所发生的事情有些迷茫.我是否错过了一些说明我们只能在特定条件下使用秒表的文档?

So I am a little bit lost as to what is going on. Did I miss some documentation stating that we can only use Stopwatch under certain conditions?

推荐答案

你好Wabbite,

Hi Wabbite,

谢谢您在这里发布.

对于您的问题,优化后的代码是什么意思?

For your question, what does the optimized code mean?

秒表类用于精确测量经过的时间.据我所知,它不能用于优化代码.

The Stopwatch class is used to accurately measure elapsed time. As I know, it could not use to optimized code.

秒表实例可以测量一个时间间隔的经过时间,或跨多个时间间隔的经过时间的总和.在典型的秒表场景中,您将 开始方法,然后最终调用 停止方法,然后使用

A Stopwatch instance can measure elapsed time for one interval, or the total of elapsed time across multiple intervals. In a typical Stopwatch scenario, you call the Start method, then eventually call the Stop method, and then you check elapsed time using the Elapsed property.

有关更多情况,您可以参考MSDN文章

For more condition, you could refer to the MSDN article Stopwatch Class Remarks.

如果我误解了您的意思,请随时与我们联系.

If I misunderstand what you mean, please feel free to contact us.

最好的问候,

温迪


这篇关于我们应该在优化代码中信任秒表吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆