【发布时间】:2013-04-11 02:06:31
【问题描述】:
我喜欢 Rx,但我一直遇到一个问题。
假设我们有一个单独的上游IObservable<Foo> 和N 附加到下游的序列,每个序列都只对满足一些简单谓词(比如foo.bar == someKey)的那些Foos感兴趣。
当然,这对于Where() 操作员来说是一项简单的工作:
IObservable<Foo> foos = ...;
foos.Where(foo => foo.bar == "abc").Subscribe(f => A(f));
foos.Where(foo => foo.bar == "xyz").Subscribe(f => B(f));
foos.Where(foo => foo.bar == "bla").Subscribe(f => C(f));
...
[many more subscriptions for different bar values]
这里本质上会发生的是,对于上游生成的每个 Foo,Where() 谓词将针对 Foo N 次进行评估。它就像一个线性搜索来查找所有想要这个Foo 的订阅者。这一切都很好,这正是我们(应该)在这里使用Where() 所期望的。
我遇到的问题是,就我而言,N 可能非常大,但想要任何特定 Foo 的订阅者子集非常小。通常,每个Foo 将只有一个。这意味着当我可以进行非常有效的查找以找到该Foo 也需要传播的少数下游序列时,我实际上是在进行缓慢的线性搜索。我的应用在性能非常关键的环境中运行,我无法承受这种低效率。
我绞尽脑汁想找到一些更有效的优雅方法,但我只能想出涉及存储大量状态(映射订阅者等)并且必须非常小心地管理并发的解决方案,这首先破坏了使用 Rx 的许多目的。就现有运营商而言,我更喜欢某种方式来处理这个问题。有没有人处理过这个问题,或者知道一个好的解决方案?我很乐意提供更多详细信息。
编辑
我想我的例子有点过于简单了。我不是在处理与某个已知范围内的数值匹配的情况。 N 仅用于说明目的。更新了上面的示例。
【问题讨论】:
-
你会为 bar 0..N 的所有可能值提供 foos,还是只提供一些?
-
最好的办法可能是让你的 foos 保持有序。看看
List.BinarySearch,然后迭代调用Subscribe直到foo.Bar >= N -
对不起,我的例子太简单了,请参阅编辑和新的示例代码。
标签: c# system.reactive