Created
January 20, 2023 09:50
-
-
Save serafo27/aee27d733a701781c179c4924dae7d19 to your computer and use it in GitHub Desktop.
Concurrency vs Parallelism using Kotlin coroutines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import kotlinx.coroutines.* | |
import org.junit.jupiter.api.Test | |
import org.slf4j.LoggerFactory | |
import java.math.BigInteger | |
import java.util.* | |
import kotlin.system.measureTimeMillis | |
import kotlin.time.ExperimentalTime | |
import kotlin.time.measureTimedValue | |
class ConcurrencyVsParallelismTest { | |
private val log = LoggerFactory.getLogger(this::class.java) | |
@Test | |
internal fun concurrency() { | |
runBlocking { | |
log.debug("in runBlocking") | |
val time = measureTimeMillis { | |
val one = async { doSomethingUsefulOne() } | |
val two = async { doSomethingUsefulTwo() } | |
println("The answer is ${one.await() + two.await()}") | |
} | |
println("Completed in $time ms") | |
} | |
} | |
@Test | |
internal fun `parallelism 1`() { | |
runBlocking { | |
log.debug("in runBlocking") | |
val time = measureTimeMillis { | |
val one = GlobalScope.async { doSomethingUsefulOne() } | |
val two = GlobalScope.async { doSomethingUsefulTwo() } | |
println("The answer is ${one.await() + two.await()}") | |
} | |
println("Completed in $time ms") | |
} | |
} | |
@Test | |
internal fun `parallelism 2`() { | |
runBlocking { | |
log.debug("in runBlocking") | |
val time = measureTimeMillis { | |
val one = async(Dispatchers.Default) { doSomethingUsefulOne() } | |
val two = async(Dispatchers.Default) { doSomethingUsefulTwo() } | |
println("The answer is ${one.await() + two.await()}") | |
} | |
println("Completed in $time ms") | |
} | |
} | |
@Test | |
internal fun `parallelism 3`() { | |
runBlocking { | |
log.debug("in runBlocking") | |
val time = measureTimeMillis { | |
val one = async { doSomethingElseUsefulOne() } | |
val two = async { doSomethingElseUsefulTwo() } | |
println("The answer is ${one.await() + two.await()}") | |
} | |
println("Completed in $time ms") | |
} | |
} | |
private fun doSomethingUsefulOne(): BigInteger { | |
log.debug("in doSomethingUsefulOne") | |
return BigInteger(1500, Random()).nextProbablePrime() | |
} | |
private fun doSomethingUsefulTwo(): BigInteger { | |
log.debug("in doSomethingUsefulTwo") | |
return BigInteger(1500, Random()).nextProbablePrime() | |
} | |
@OptIn(ExperimentalTime::class) | |
private suspend fun doSomethingElseUsefulOne(): BigInteger = withContext(Dispatchers.Default) { | |
measureTimedValue { | |
log.debug("in doSomethingUsefulOne") | |
BigInteger(1500, Random()).nextProbablePrime() | |
} | |
}.also { | |
log.debug("Prime calculation one took ${it.duration} ms") | |
}.value | |
@OptIn(ExperimentalTime::class) | |
private suspend fun doSomethingElseUsefulTwo(): BigInteger = withContext(Dispatchers.Default) { | |
measureTimedValue { | |
log.debug("in doSomethingUsefulTwo") | |
BigInteger(1500, Random()).nextProbablePrime() | |
} | |
}.also { | |
log.debug("Prime calculation two took ${it.duration} ms") | |
}.value | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment