我正在使用Observable.Interval来测试特定客户端/服务器代码在不同负载下的性能。
但这似乎有些奇怪的行为。
Observable.Interval(timespan = 0)
尽可能快地生成事件,例如每秒800万个事件。好像还可以Observable.Interval(0 < timespan < 1ms)
只产生1个事件,然后什么也没有。Observable.Interval(1ms <= timespan)
以大约所请求的速率生成事件,量化程度很高,并且最多每秒最多只有64个事件。我可以理解,它不一定在下面使用高分辨率计时器,但令人困惑的是,它在三个区域中的行为完全不同。
这是预期的行为,还是我使用错了?如果可以预期,那么可以使用Observable.Interval的替代方法在Rx中模拟高频事件源,还是应该自己滚动...?
下面是一个演示该行为的简短程序:
static void Main(string[] args)
{
const int millisecsPerTest = 10000;
var intervals = new[]
{
TimeSpan.FromTicks(0), // 0 -> rate of 8M messages per second
TimeSpan.FromTicks(1000), // 0.1ms -> rate of 0
TimeSpan.FromTicks(20000), // 2ms -> rate of 64 messages per second (not 500 as expected)
TimeSpan.FromTicks(1000000), // 100ms -> rate of 9 messages per second
};
foreach(var interval in intervals)
{
long msgs = 0;
using (Observable.Interval(interval).Subscribe(
l => { ++msgs; },
e => Console.WriteLine("Error {0}", e.Message),
() => Console.WriteLine("Completed")))
{
Thread.Sleep(millisecsPerTest);
}
Console.WriteLine("Interval: {0} ticks, Events: {1}, Rate: {2} events per second", interval.Ticks, msgs, (int)(msgs/(double)millisecsPerTest*1000));
}
}
是的,我认为.net Framework计时器使用的时钟仅间隔16毫秒运行,因此您的结果不会令我感到惊讶。尽管您的1个刻度间隔测试听起来像个错误。您使用的是哪个OS,Rx版本,.Net版本?我看看能否解决这个问题。
对于0打勾的情况,我认为您正在获得较高的吞吐量,因为Rx调度程序检测到工作是“现在”到期,并且只是立即启动它并绕过.Net计时器来调度工作。
使用Observable.Create可以很容易地创建您自己的Interval版本,该版本使用更高分辨率的计时器。稍微复杂一点但最终更有用的是编写一个使用高分辨率计时器的新IScheduler实现。然后,您可以将该调度程序传递给所有现有的与时间相关的Rx方法。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句