【问题标题】:For loop randomly takes more ticks?For循环随机需要更多滴答声?
【发布时间】:2016-06-05 21:43:51
【问题描述】:

我正在测试我的代码以查看 for 和 foreach 循环之间的性能差异(出于好奇,我想看看它如何影响我的程序),并且在测量滴答声时,我注意到会有零星的跳转在 for 循环中列表为空时所用的时间。

例如,控制台窗口中的某些输出显示为 [...], 2, 4, 4, 2, 5, 4, 2, 26, 3, 1, 27, 2, 2, 1, 3, 2, 2, [...]。

虽然我意识到对于如此小的时间间隔测量的这些滴答对我的应用程序的最终性能来说是疏忽的,但我很好奇为什么会有这样的跳跃。同样,这些数字是在我知道列表为空时获取的,因此实际上没有什么可以迭代。

循环中的对象是字典;具体来说,它们具有用于键的整数和用于其值的自定义类。

Stopwatch.Frequency 给了我 2533211(因为我进行了之前的测量,所以我不必重新启动系统)。

代码 -

    public void Update(int gameTime)
    {
        watch.Restart();
        for (int i = 0; i < _movementComponents.Count; ++i)
        {
            _positionComponents[i].Position += _movementComponents[i].Velocity * gameTime;
            _movementComponents[i].Velocity = Vector2.Zero;
        }
        watch.Stop();
        Console.WriteLine("Loop took " + watch.ElapsedTicks + " ticks");
    }

【问题讨论】:

  • 垃圾回收可能吗?
  • 您在循环中操作和创建的对象是什么?我的第一个猜测是GC。特别是如果你没有在那里使用值类型。
  • 刻度的频率非常相关。这是纳秒级吗?微秒?可能是缓存未命中、上下文切换等。
  • 我用 empty 循环做了一个这样的实验。那里也发生。例如,来自(网络)中断的背景噪音。或者做少量工作的高优先级线程。
  • 更新了我的帖子以包含请求的信息; @Joey,即使没有迭代它们,被操纵的对象也会很重要吗?

标签: c# performance loops diagnostics


【解决方案1】:

我做了一个空循环的实验。在那里也发现了相同的随机延迟。以下是我能想到的几个原因:

  • 中断(网络、鼠标、计时器滴答声、其他进程导致的 IO 完成、音乐播放器、USB 设备同步传输……)
  • 高优先级线程在进入睡眠之前执行少量工作。我想不出任何具体的这样的线程,但我知道这是一个原因。当您将自己的线程和进程设置为实时时,延迟配置文件会显着压缩。
  • 也许您正在触摸待机列表中的内存页面。这意味着访问时发生软页面错误。
  • 垃圾收集器可能会被我触发,而不是这个循环。

【讨论】:

  • 您始终可以通过检查 Gen 0 GC 计数来检查是否调用了 GC。
猜你喜欢
  • 1970-01-01
  • 2015-08-04
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多