Skip to content

Instantly share code, notes, and snippets.

@serafo27
Created January 20, 2023 09:50
Show Gist options
  • Save serafo27/aee27d733a701781c179c4924dae7d19 to your computer and use it in GitHub Desktop.
Save serafo27/aee27d733a701781c179c4924dae7d19 to your computer and use it in GitHub Desktop.
Concurrency vs Parallelism using Kotlin coroutines
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