我正在使用observable.interval来测试特定的客户端/服务器代码在不同加载下的性能。
,但似乎有一些奇怪的行为。
-
Observable.Interval(timespan = 0)
尽快产生事件,例如每秒800万事件。这似乎还可以。 -
Observable.Interval(0 < timespan < 1ms)
仅产生1个事件,然后什么也没有。 -
Observable.Interval(1ms <= timespan)
以大约需要的速率生产事件,非常量化,最多只有64个事件/秒。
我可以欣赏它不一定使用下面的高RES计时器,但是令人困惑的是,它在这三个区域中具有完全不同的行为。
这是预期的行为,还是我使用的是错误的?如果是预期的,那么是否有可观察的替代方法。用于模拟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个tick间隔测试听起来像是一个错误。您使用的是什么OS,RX版本,.NET版本?我看看我是否可以重复这个问题。
对于0个tick案例,我认为您的吞吐量很高,因为RX调度程序正在检测到工作是"现在"的,并且只是立即启动它并绕过.NET计时器以安排工作。
。使用可观察到的易于使用。创建使用更高分辨率计时器的间隔版本。更复杂,但最终更有用的是编写使用高分辨率计时器的新的Ischeduler实现。然后,您可以将该调度程序传递给所有现有时间相关的RX方法。