2017-01-26 6 views
2

Какова разница в производительности между следующими фрагментами кода?Couchbase RX Client - Объединение нескольких наблюдаемых против flatmap

Использование: извлечение нескольких ключей из Couchbase с использованием реактивного SDK Couchbase.

Отрывок # 1

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

Сниппет # 2

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

Первый фрагмент кода рекомендуемый способ в соответствии с СВ-х documentation.

Кроме того, в самом конце наблюдаемой является преобразованный в блокирующий, , но все до этого, включая сетевые вызовы и агрегация , происходит полностью асинхронно.

Внутри SDK, это обеспечивает гораздо более эффективное использование ресурсов , поскольку запросы очень быстро сохраняются во внутреннем запросе RingBuffer и потоков ввода/вывода в состоянии выбрать партии, как большие, как они могут. После этого, любой сервер возвращает результат сначала , хранящийся в списке, поэтому сериализация ответов не происходит. on.

Второй фрагмент представляет собой случай, мы нашли в нашем кодовую сегодня, где есть список наблюдаемых, где каждый наблюдаемый вызывает метод GET роторного один за другим, а затем объединяет их всех.

ответ

1

Там не должно быть никакой разницы в производительности между этими двумя отрывками, с точки зрения как в Couchbase SDK и RxJava, они очень похожи (как flatMap основном сделать map к Observables как ваш keys.forEach, то merge наблюдаемые в петля).

редактировать: с личной точки зрения я все еще предпочитаю первый стиль, хотя;)

1

Что делает flatMap, он вызывает функцию сопоставления для каждого ключа, а затем объединяет результаты этих вызовов. Я не ожидаю, что этот алгоритм слияния будет отличаться от того, который используется в merge. Поэтому в случае, если bucket.get() не блокирует, не должно быть разницы в производительности между ними.

Фрагмент №1 выглядит более читабельным для меня.

+0

Согласитесь, редактирование второго фрагмента коды просто сделать вопрос яснее. RX-мудрый, я понимаю, что производительность должна быть одинаковой. Интересно, есть ли разница в том, как SDK управляет своим внутренним буфером и ресурсами при вызове этих двух примеров. – shays10

+1

@ shays10 По тому же алгоритму я имею в виду такую ​​же или очень похожую внутреннюю реализацию. Поэтому в любом аспекте не должно быть различий. –