有效地将大量rx可观察量一起采样

时间:2016-12-14 08:13:16

标签: rx-java

我有大量的observable,并希望将它们聚合成一个值。他们以高频率更新,并认为必须使用“有损”背压策略。我选择sample但是类似的东西都可以接受。 我想知道这样做的最有效(性能和/或资源方式)是什么。有两种方法是显而易见的:

val list : Iterable[Observable[Double]] = ???
val f : (Double,Double) => Double = ???
(Observable combineLatest list) sample (1 second) reduce f

或者

combineLatest (list map (_ sample (1 second)) ) reduce f

我认为这是一个非常常见的用例是公平的。为了减少这种抽象,想象一下我有许多温度传感器可以连续发射数据。这些将是我list的元素。它们以SI为单位产生温度,我想计算平均温度(这是f)。我还想选择以摄氏度或华氏度显示结果。

  1. 上述两种方法中的哪一种(尽管欢迎任何其他建议)将更有效的空间/时间?
  2. 说我不仅要显示平均温度,还要显示个别(可能已转换)的温度。这会影响答案吗?
  3. 如果Observable来自不同的来源(例如在不同的线程上观察)与它们是否来自单个序列化流(例如,单个可观察的groupBy运算符的结果),您的答案是否会改变。
  4. 考虑到我上面所说的背压,如果这个要求被取消,你的答案会有所不同(即不需要重新取样)。

1 个答案:

答案 0 :(得分:0)

我认为as运算符在这里很有用。就我而言,我不是只有一堆可观察者;我有很多拥有 observables的东西。所以首先我创建了一个帮助器类来将每个东西与它的observable相关联:

public class Pair<K, V>{
    private final K mKey;
    private final Observable<V> mValues;

    public Pair(final K key, final Observable<V> values) {
        mKey = key;
        mValues = values;
    }
    public K key() {
        return mKey;
    }

    public Observable<V> values() {
        return mValues;
    }
}

然后我创建了ObservableConverter,将Observable<Pair<K,V>>转换为Observable<Map<K,V>>。它会定期发出包含每个V的最新K的地图:

public class MapLatest<K, V> implements ObservableConverter<Pair<K, V>, Observable<Map<K, V>>> {
    private final PublishSubject<Map<K,V>> mPub = PublishSubject.create();
    private final Map<K, V> mMap = new ConcurrentHashMap<>();

    @Override
    public Observable<Map<K, V>> apply(final Observable<Pair<K, V>> pairs) {
        pairs.subscribe(this::subscribe);
        return mPub;
    }

    private void subscribe(final Pair<K,V> pair) {
        final K k = pair.key();
        pair.values().doOnNext(v -> mMap.put(k, v)).doOnTerminate(() -> mMap.remove(k));
    }
}

我的&#34;事物&#34;是玩家,我想定期建立他们位置的R树。因此,我将玩家与他们的位置可观察对配对,然后应用MapLatest

players.map(player -> new Pair<>(player, player.location()))
    .as(new MapLatest<>()).subscribe(...);

请注意,我没有在MapLatest中显示实际发出任何内容的任何代码。我正在考虑各种方法来做到这一点:

  • 使用MapLatest构造Observable<?>,并在该observable发出时发出。
  • 使用MapLatest构造Predicate<V>,当它应该发出时返回true。
  • MapLatest emit方法并从外部触发排放。

另请注意,Observable<Map<K,V>>永远不会终止。就我的目的而言,这是故意的。