In the second test there is no joining of tasks. You start them but do not wait for them to finish.
As for courutines (I am an neophyte myself), I believe is that the greatest advantage will be that you get explicit result of futures in a non blocking way. In your example you will have to call blocking join to obtain them. The internal mechanics in both of your examples is precisely the same since in this case coroutines are backed by commonPool.
Well, I believe that executor.invokeAll waits until finish. Otherwise the second test won’t cost that much.
In my opinion, the update operation will suspend when communicating with database server, so if I use a dispatcher with less thread on coroutines, it will still work fast, am I right?
friendly: you simply made a database benchmark, and you made it wrong.
The fun a and the fun c are different, so results are not comparable.
The fun c is right after the `fun a, so I can suppose that the database is entirely in the ram disk buffer, so the result is not comparable.
The fun a and fun b start using a cold JVM, so everything run later it will run faster.
CommonPool and ForkJoinPool.commonPool have different number of thread, so parallelism is different and the result is not comparable.
Finally you must not use a cpu bounded thread pool for blocking operations, your 386 can send hundred of SQL update without any issue, so use a different thread pool, but you should never use CommonPool or ForkJoinPool.commonPool.
@fvasco So what I’m confused about is whether coroutines can improve throughput of an application full of blocking I/O operations like JDBC.
You mentioned about I should use another thread pool for JDBC, does this mean coroutines won’t decrease the number of threads I use? As we all know JDBC doesn’t have async api, so can I benefit from coroutines in this scenario? If i can, what am I supposed to do?
Yes, you are right. At least according to documentation. Sadly I am not able to run test myself right now. But I think that in order coroutines you should start with artificial tests. DB access complicates things.
Coroutines work best when you do use suspending functions. Without suspending functions, threads work just as well as coroutines. However, if you are looking for consistency and want to have coroutines-only code without any mix, then it is perfectly Ok to use coroutines even for the code that does not do any suspension.