Reputation: 11559
I had a hunch that for highly computational, parallelized tasks in RxJava, a traditional ExecutorService
would be faster than a Scheduler
.
I had a theory that this code
Observable<MyItem> source = ...
source.flatMap(myItem -> myItem.process().subscribeOn(Schedulers.computation()))
.subscribe();
would run slower than this
final ExecutorService svc = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
Observable<MyItem> source = ...
source.flatMap(myItem -> myItem.process().subscribeOn(Schedulers.from(svc)))
.finallyDo(svc::shutdown)
.subscribe();
I compared these two approaches with a typical parallel process I do at work, and I got the following results.
EXECUTOR
START: 2016-01-25T09:47:04.350
END: 2016-01-25T09:48:37.181
TOTAL TIME (SEC): 92
COMPUTATION SCHEDULER
START: 2016-01-25T09:50:37.799
END: 2016-01-25T09:54:23.674
TOTAL TIME (SEC): 225
So my rough testing has shown the traditional ExecutorService
is much faster than a Scheduler
for computation.
Is there a reason for these results? Are RxJava schedulers just not optimized for parallelization? I've gotten the impression that computation schedulers use lesser threads than Executors.
Upvotes: 18
Views: 11474
Reputation: 175
When you use Schedulers.computation()
, all the events are handled in the same thread. You can refer to the source code CachedThreadScheduler.java
and NewThreadWorker.java
. The benefit of this implementation is that if eventA is emitted after eventB, then eventA will be handled after eventB.
When you use Schedulers.from()
, the events are handled in different threads.
Upvotes: 3
Reputation: 11559
I did several tests and discovered that creating your own ExecutorService
can in fact increase parallelization performance. I wrote a blog post on it here.
Upvotes: 15