RX Observable - 测量执行时间(即使嵌套时)

时间:2016-09-07 15:15:45

标签: java rx-java

我使用附加的类来测量我的observable的执行时间。只要我不测量嵌套的可观察量,这种方法就可以了。

工作正常

Observable<T> obs1 = ...;
Observable<T> obs2 = ...;

obs1
    .compose(RXMeasure.applyMeasurement(T.class, "tag1"))
    .subscribe();

obs2
    .compose(RXMeasure.applyMeasurement(T.class, "tag2"))
    .subscribe();

无效

Observable<T> obs3 = ...;

Observable<T> obs = obs1
    .flatMap(resul1 -> obs2)
    .flatMap(result2 -> obs3)
    .subscribe();

这导致结果,所有可观测量都在开始时订阅,这意味着测量不再正确。在这里,我试图按顺序执行3个可观测量...

我想要什么

我想要一个

的度量函数
  • 没有打破链条
  • 测量一个observable的执行时间(类似于observable的开始/结束而不是subscribe / terminate之间的时间)

有什么想法吗?

RXMeasure课程

public class RXMeasure
{
    private static boolean mEnabled = true;

    public static void setEnabled(boolean enabled)
    {
        mEnabled = enabled;
    }

    public static <T> Observable.Transformer<T, T> applyMeasurement(Class clazz, String tag)
    {
        return observable -> measure(observable, clazz, tag);
    }

    public static <T> Observable<T> measure(Observable<T> observable, Class clazz, String tag)
    {
        if (!mEnabled)
            return observable;

        LongHolder start = new LongHolder(0);
        return observable
                .doOnSubscribe(() -> start.set(System.currentTimeMillis()))
                .doOnTerminate(() -> L.d(clazz, "[" + tag + "] Duration: " + String.valueOf(System.currentTimeMillis() - start.get()) + "ms"));
    }
}

2 个答案:

答案 0 :(得分:1)

嗯......如果你想按顺序运行它们并且它们没有任何数据依赖性,那么这项工作是否胜利?

Observable.concatMap(
  obs1.compose(applyMeasurement(T.class, "tag1")),
  obs2.compose(applyMeasurement(T.class, "tag2")),
  obs3.compose(applyMeasurement(T.class, "tag3")),
).subscribe();

否则,您需要更好地定义术语&#34;执行时间&#34;,尤其是对于可能多次订阅的可观察量。

编辑:它看起来像普通的concat是一个解决方案:

Observable<Observable<T>> obss = Observable.just(
  obs1.compose(applyMeasurement(T.class, "tag1")),
  obs2.compose(applyMeasurement(T.class, "tag2")),
  obs3.compose(applyMeasurement(T.class, "tag3")),
);

Observable.concat(obss).subscribe();

我对docs和RxJava源代码的理解是concat将在上一个Observable完成/取消后被订阅。

答案 1 :(得分:0)

这是我迄今为止最好的解决方案:

<强>解释

我只是强制所有的observable都是顺序运行的,不是通过链接运行,而是通过辅助函数...

<强>代码

RXUtil.executeSequentially(
            observable -> {
                // subscribe the way you want
                observable.subscribe();
            },
            true,
            obs1,
            obs2,
            obs3);
}

RXUtil类

public class RXUtil 
{
    public static Observable executeSequentially(ISubscribe subscribe, boolean startObserving, Observable... observables)
    {
        for (int i = 0; i < observables.length - 1; i++)
        {
            final int fI = i;
            Observable observable = observables[i]
                    .doOnCompleted(new Action0() {
                        @Override
                        public void call() {
                            subscribe.subscribe(observables[(fI + 1)]);
                        }
                    });
            observables[i] = observable;
        }
        if (startObserving)
            subscribe.subscribe(observables[0]);
        return observables[0];
    }

    public interface ISubscribe<T>
    {
        void subscribe(Observable<T> observable);
    }
}