为啥这段代码的执行速度比预期的要快?
Posted
技术标签:
【中文标题】为啥这段代码的执行速度比预期的要快?【英文标题】:Why is this code executing faster than expected?为什么这段代码的执行速度比预期的要快? 【发布时间】:2009-04-03 14:49:20 【问题描述】:我有这个代码:
public void replay()
long previous = DateTime.Now.Ticks;
for (int i = 0; i < 1000; i++)
Thread.Sleep(300);
long cur = DateTime.Now.Ticks;
Console.WriteLine(cur - previous);
previous = cur;
像这样作为单独的线程调用:
MethodInvoker replayer = new MethodInvoker(replay);
replayer.BeginInvoke(null, null);
但是,如果我查看输出,它的行为会很奇怪。它成对输出i
。例如,它会等待一个完整的等待,然后输出i
,然后也快速输出下一个i
,然后再次等待。为什么会这样,我该如何纠正?
它输出这个:
3125040
2968788
2968788
2968788
3125040
2968788
2968788
2968788
3125040
2968788
2968788
2968788
3125040
如果我将睡眠时间增加到一秒以上,这不会发生。
【问题讨论】:
首先,这是发布模式还是调试模式?其次,使用计时器而不是仅仅观看控制台输出 - 不能保证控制台会立即显示内容。 你确定这不是在控制台缓冲吗? 查看输出,小于 5 % 的差异是循环执行之间的延迟......感知到的差异只是在显示中...... 【参考方案1】:更改代码以消除分析中的显示延迟:
public void replay()
Thread.Sleep(5000);
DateTime start = DateTime.Now;
for (int i = 0; i < 1000; i++)
Console.WriteLine(string.Format("Exec:0 - 1 ms",
i, DateTime.Now - start));
start = DateTime.Now;
Thread.Sleep(300);
查看您修改后的输出,循环延迟的方差不到 5%(300 个中的 15 毫秒)。这是正常的,因为操作系统实际将时间片分配给线程时所涉及的不确定性......(如果我没记错的话,在 Windows 操作系统中,这通常是每 20 毫秒!)
您在控制台输出中看到的较大差异几乎可以肯定是由于显示延迟。
【讨论】:
【参考方案2】:无法复制。我想知道它是否是您机器本地的东西;缓冲,也许吧。
【讨论】:
同上。调出任务管理器并查看您的流程。我怀疑有些东西正在消耗周期。 建议 OP 将输出写入其他内容 - 也许是 Dictionary我无法重现此内容,但您可能需要考虑使用计时器。它会更可靠。
public class Counter
private readonly TimeSpan initialDelay, incrementDelay;
private readonly int maxCount;
private Timer timer;
private int count;
public Counter(TimeSpan initialDelay, TimeSpan incrementDelay, int maxCount)
this.maxCount = maxCount;
this.initialDelay = initialDelay;
this.incrementDelay = incrementDelay;
public void Start(Action<int> tickBehavior)
if (timer != null)
Timer temp = timer;
timer = null;
temp.Dispose();
timer = new Timer(() =>
tickBehavior(count++);
if (count > maxCount) timer.Dispose();
, null, initialDelay, incrementDelay);
使用它:
Counter counter = new Counter(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(.3), 1000);
counter.Start((count) => Console.WriteLine(count););
编辑
我正在使用System.Threading.Timer
,但Counter
可以根据您的需要轻松修改为使用System.Timers.Timer
或System.Windows.Forms.Timer
。请参阅this link for a description 了解何时使用哪些计时器。
【讨论】:
+1 那段代码是我整个星期见过的最酷的东西 :)【参考方案4】:您在循环中的睡眠时间只有 300 毫秒,这不是很长。您的应用程序将执行以下操作:
睡眠 5 秒 打印 0 睡眠 300 毫秒 打印 1 睡眠 300 毫秒 打印 2等等
【讨论】:
但事实并非如此,这就是问题所在。以上是关于为啥这段代码的执行速度比预期的要快?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security 时,会话超时比预期的要快
为啥在 C# .NET 中写入 Excel 范围所需的时间比预期的要长得多?