2016-10-10 15 views
0

私はコードベースでrxJavaを試していましたが、パフォーマンスを向上させる並行性を追加することがほとんどでした。しかし、rxJavaを使用すると、オーバーヘッド/起動コストの問題があるようです。以下の例では、 "doRx()"ではgetAllElements()がトリガーされる前に130msかかり、 "doOld"ではgetAllElements()がトリガーされるまでに0msかかる。何故私が最初にdoRx()で130msを失っているのかについての説明?rxJavaのオーバーヘッド

これは、System.currentTimeMillis()を使用して私が行うログです。 ()はinit()からの経過時間です。

既存の実装

  • (0)2016-10-11T13:34:07.060:OldImpl:INIT()
  • (0)2016-10-11T13:34:07.060:OldImplは:getAllElementsコール()
  • (327)2016-10-11T13:34:07.387:OldImpl:受信getAllElements()

RX実装

  • (0)2016-10-11T13:34:07.703:RxImpl:INIT()
  • ()2016-10-11T13:34:07.863:RxImpl: getAllElements()
  • (392コール)2016-10-11T13:34:08.095:RxImpl:コードの背後にある理由は、私が最初にすべての要素を収集し、その後、H 2下(並列に実行したいということです

受信getAllElements())以来、多くのバックエンド呼び出しがあるので、時間を節約することができます。私はthis blogをこの設定のガイダンスとして使用しました。

public List<Element> doRx() { 

    List<Element> elements = new ArrayList<>(); 

    Observable 
      .from(getAllElements()) 
      .flatMap(
        s -> Observable 
          .just(Element::new) 
          .subscribeOn(Schedulers.io()) 
          .flatMap(
            e -> { 

             List<Element> elements = new ArrayList<>(); 

             for (SubElement se : e.getSubElements()) { 

              elements.add(se); 

             } 

             return Observable.from(elements); 
            } 
          ) 
      ) 
      .flatMap(

        h1 -> Observable 
          .just(h1) 
          .subscribeOn(Schedulers.computation()) 
          .flatMap(
            h2 -> { 

             // Do additional things in parallell on all elements 

             return Observable 
               .just(h2); 
            } 
          ) 
      ) 
      .toBlocking() 
      .getIterator() 
      .forEachRemaining(myList::add); 

    return elements; 
} 


public List<Element> doOld() { 

    List<Element> elements = getAllElements(); 

    for (Element e : elements) { 
     // Do stuff, same as under h2 
    } 

    return elements; 
} 
+0

古い_sequential_コードで2つ以上のスレッドが使用されましたか? – miensol

+0

いいえ、スレッドは1つだけです。逐次性は貧しい言葉の選択でした。同期は私が意味するものでした。 getElements()はここでの実行の最初のステップです。 – user1682170

+0

あなたはh2がシングルスレッドデータベースであることを認識していますか? –

答えて

1

私はあなたが正しくコーディング理解していれば、それは以下と等価です:

public List<Element> doRx() { 
    return Observable 
     .from(getAllElements()) 
     .flatMap(element -> Observable 
      .just(new Element(element)) 
      .subscribeOn(Schedulers.io()) 
      .flatMaplIterable(e -> e.getSubElements()) 
     ) 
     .observeOn(Schedulers.computation()) 
     .doOnNext(element -> { 
      // Do additional things in parallell on all elements 
     }) 
     .toList() 
     .toBlocking() 
     .single(); 
} 

これは、最小2文脈で、順次バージョンよりも多くの要素ごとに切り替わりました。どのようにあなたのタイミングをやっている? Xは実行され、最大値と最小値は無視されますか?

+0

同等であると思われます。これにマッチするように私のコードを書き直してください。それはうまくいきましたが、タイミングは変わりませんでした。 – user1682170

+0

私はあらゆる徹底的な負荷テストを行ったわけではありません。私はこれを数回実行するだけの簡単なテストをしています。今度は15回ランする前にgetElements()を呼び出す前に100〜150ms "lost"と同じように見える – user1682170

+0

"Ran"と言うと、 'java -jar ... 'を15回実行したことを意味しますか?あるいはあなたのコードは 'time(() - > doRx);'それは次々に15回ですか? –

関連する問題