2

What is the performance difference between the following code snippets?

Use case: retrieve multiple keys from Couchbase using the Couchbase reactive SDK.

Snippet #1

 return Observable
            .from(keys)
            .flatMap(id ->
                    bucket.get(id, RawJsonDocument.class)
            )
            .toList()
            .toBlocking()
            .single();

Snippet #2

     List<Observable<RawJsonDocument>> list = new ArrayList<>();
     keys.forEach(key -> list.add(bucket.get(key, RawJsonDocument.class)));
     return Observable.merge(list)
            .toList()
            .toBlocking()
            .single();

The first snippet is the recommended way according to CB's documentation.

Also, at the very end the observable is converted into a blocking one, but everything before that, including the network calls and the aggregation, is happening completely asynchronously.

Inside the SDK, this provides much more efficient resource utilization because the requests are very quickly stored in the internal Request RingBuffer and the I/O threads are able to pick batches as large as they can. Afterward, whatever server returns a result first it is stored in the list, so there is no serialization of responses going on.

The second snippet is a case we found in our codebase today, where there's a list of Observables, where each observable triggers a get method of Bucket one by one and then merges them all.

shays10
  • 509
  • 5
  • 18

2 Answers2

1

What flatMap does it invokes mapper function for each key, then merges results of these invocations. I don't expect this merging algorithm to be any different from the one used in merge. So in case bucket.get() is non-blocking, there should be no performance difference between the two.

Snippet #1 looks more readable to me.

Yaroslav Stavnichiy
  • 20,738
  • 6
  • 52
  • 55
  • Agree, editing the second snippet just to make the question clearer. RX-wise, I understand the performance should be identical. I wonder if there's a difference on how the SDK manages its inner buffer and resources when invoking those 2 examples. – shays10 Jan 26 '17 at 13:15
  • 1
    @shays10 By same algorithm I mean same or very similar internal implementation. Therefore there should be no differences in any aspect. – Yaroslav Stavnichiy Jan 27 '17 at 05:18
1

There should be no performance difference between the two snippets, from the perspective both of the Couchbase SDK and RxJava, they are very similar (as flatMap basically do a map to Observables like your keys.forEach, then merge the observables in a loop).

edit: from a personal perspective I still prefer the first style though ;)

Simon Baslé
  • 27,105
  • 5
  • 69
  • 70