Last active
June 24, 2018 12:30
-
-
Save anthonynsimon/a15841cac4efc20a22855819df953839 to your computer and use it in GitHub Desktop.
Skynet benchmark
This file contains hidden or 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.experimental.* | |
import kotlinx.coroutines.experimental.channels.Channel | |
import java.util.concurrent.atomic.AtomicLong | |
import kotlin.concurrent.thread | |
fun main(args: Array<String>) { | |
// bench("threads") { skynetThread(0, 1000000, 10) } // Out of Memory error | |
bench("sync") { skynetSync(0, 1000000, 10) } | |
bench("coroutines-async") { skynetCoroutinesAsync(0, 1000000, 10) } | |
bench("coroutines-launch") { skynetCoroutinesLaunch(0, 1000000, 10) } | |
bench("channels") { skynetChannels(0, 1000000, 10) } | |
} | |
fun bench(name: String, times: Int = 10, func: () -> Long) { | |
println("Running $name...") | |
repeat(times) { | |
val start = System.nanoTime() | |
val result = func() | |
val duration = (System.nanoTime() - start) / 1e6 | |
println("result $name: ${result} took: ${duration} ms") | |
} | |
} | |
fun skynetSync(num: Int, size: Int, div: Int): Long { | |
if (size == 1) return num.toLong() | |
else return (0 until div) | |
.map { i -> skynetSync(num + i * (size / div), size / div, div) } | |
.sum() | |
} | |
fun skynetThread(num: Int, size: Int, div: Int): Long { | |
if (size == 1) return num.toLong() | |
val sum = AtomicLong() | |
repeat(10) { i -> | |
thread { | |
val childSum = skynetThread(num + i * (size / div), size / div, div) | |
sum.addAndGet(childSum) | |
} | |
} | |
return sum.get() | |
} | |
fun skynetCoroutinesAsync(num: Int, size: Int, div: Int): Long { | |
fun _child(num: Int, size: Int, div: Int): Deferred<Long> = async { | |
if (size == 1) num.toLong() | |
else { | |
val children = (0 until 10).map { i -> _child(num + i * (size / div), size / div, div) } | |
children.map { it.await() }.sum() | |
} | |
} | |
return runBlocking { _child(num, size, div).await() } | |
} | |
fun skynetCoroutinesLaunch(num: Int, size: Int, div: Int): Long { | |
val sum = AtomicLong() | |
fun _child(num: Int, size: Int, div: Int): Job = launch { | |
if (size == 1) sum.addAndGet(num.toLong()) | |
else (0 until 10) | |
.map { i -> _child(num + i * (size / div), size / div, div) } | |
.forEach { it.join() } | |
} | |
return runBlocking { | |
_child(num, size, div).join() | |
sum.get() | |
} | |
} | |
fun skynetChannels(num: Int, size: Int, div: Int): Long { | |
val resultChan = Channel<Long>() | |
fun _child(num: Int, size: Int, div: Int, chan: Channel<Long>): Job = launch { | |
if (size == 1) chan.send(num.toLong()) | |
else { | |
var sum = 0L | |
val sumChan = Channel<Long>() | |
repeat(10) { i -> | |
_child(num + i * (size / div), size / div, div, sumChan) | |
} | |
repeat(10) { | |
sum += sumChan.receive() | |
} | |
sumChan.close() | |
chan.send(sum) | |
} | |
} | |
return runBlocking { | |
_child(num, size, div, resultChan) | |
resultChan.receive() | |
} | |
} |
This file contains hidden or 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 java.util.concurrent.Executors | |
import scala.concurrent.duration.Duration | |
import scala.concurrent.{Await, ExecutionContext, Future} | |
object Main { | |
def main(args: Array[String]): Unit = { | |
implicit val ec = ExecutionContext.fromExecutor(Executors.newWorkStealingPool()) | |
bench("sync") { skynetSync(0, 1000000, 10) } | |
bench("futures") { skynetFutures(0, 1000000, 10) } | |
// bench("actors") { skynetActors(0, 1000000, 10) } | |
} | |
def bench(name: String, times: Int = 10)(block: => Long) = { | |
println(s"Running $name...") | |
(0 until times).foreach { _ => | |
val start = System.nanoTime() | |
val result = block | |
val duration = (System.nanoTime() - start) / 1e6 | |
println(s"result $name: $result took: $duration ms") | |
} | |
} | |
def skynetSync(num: Int, size: Int, div: Int): Long = { | |
if (size == 1) num | |
else (0 until div).map(i => skynetSync(num + i*(size/div), size/div, div)).sum | |
} | |
def skynetFutures(num: Int, size: Int, div: Int)(implicit executionContext: ExecutionContext): Long = { | |
def _child(num: Int, size: Int, div: Int): Future[Long] = { | |
if (size == 1) Future.successful(num) | |
else Future.sequence((0 until div).map(i => _child(num + i * (size / div), size / div, div))).map(_.sum) | |
} | |
Await.result(_child(num, size, div), Duration.Inf) | |
} | |
// def skynetActors(num: Int, size: Int, div: Int)(implicit actorSystem: ActorSystem): Long = ??? | |
} |
This file contains hidden or 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
==== Kotlin ==== | |
Running sync... | |
result sync: 499999500000 took: 78.530253 ms | |
result sync: 499999500000 took: 46.281675 ms | |
result sync: 499999500000 took: 14.877077 ms | |
result sync: 499999500000 took: 13.812556 ms | |
result sync: 499999500000 took: 12.982618 ms | |
result sync: 499999500000 took: 14.750728 ms | |
result sync: 499999500000 took: 12.540582 ms | |
result sync: 499999500000 took: 14.040338 ms | |
result sync: 499999500000 took: 14.960383 ms | |
result sync: 499999500000 took: 32.027634 ms | |
Running coroutines-async... | |
result coroutines-async: 499999500000 took: 1693.764577 ms | |
result coroutines-async: 499999500000 took: 1442.738373 ms | |
result coroutines-async: 499999500000 took: 558.769895 ms | |
result coroutines-async: 499999500000 took: 468.704341 ms | |
result coroutines-async: 499999500000 took: 309.511122 ms | |
result coroutines-async: 499999500000 took: 295.281503 ms | |
result coroutines-async: 499999500000 took: 274.425134 ms | |
result coroutines-async: 499999500000 took: 237.899334 ms | |
result coroutines-async: 499999500000 took: 257.825042 ms | |
result coroutines-async: 499999500000 took: 322.748843 ms | |
Running coroutines-launch... | |
result coroutines-launch: 499999500000 took: 321.341801 ms | |
result coroutines-launch: 499999500000 took: 247.820448 ms | |
result coroutines-launch: 499999500000 took: 200.346479 ms | |
result coroutines-launch: 499999500000 took: 242.544458 ms | |
result coroutines-launch: 499999500000 took: 198.280846 ms | |
result coroutines-launch: 499999500000 took: 275.346196 ms | |
result coroutines-launch: 499999500000 took: 202.718254 ms | |
result coroutines-launch: 499999500000 took: 339.326855 ms | |
result coroutines-launch: 499999500000 took: 199.605175 ms | |
result coroutines-launch: 499999500000 took: 212.286115 ms | |
Running channels... | |
result channels: 499999500000 took: 848.969901 ms | |
result channels: 499999500000 took: 551.106903 ms | |
result channels: 499999500000 took: 379.826516 ms | |
result channels: 499999500000 took: 413.250208 ms | |
result channels: 499999500000 took: 474.846472 ms | |
result channels: 499999500000 took: 504.460687 ms | |
result channels: 499999500000 took: 386.361889 ms | |
result channels: 499999500000 took: 456.965036 ms | |
result channels: 499999500000 took: 597.235443 ms | |
result channels: 499999500000 took: 416.664959 ms | |
==== Scala ==== | |
Running sync... | |
result sync: 499999500000 took: 138.729668 ms | |
result sync: 499999500000 took: 34.332871 ms | |
result sync: 499999500000 took: 35.911405 ms | |
result sync: 499999500000 took: 73.810535 ms | |
result sync: 499999500000 took: 33.670636 ms | |
result sync: 499999500000 took: 33.476382 ms | |
result sync: 499999500000 took: 59.939789 ms | |
result sync: 499999500000 took: 86.468402 ms | |
result sync: 499999500000 took: 33.078457 ms | |
result sync: 499999500000 took: 30.488075 ms | |
Running futures... | |
result futures: 499999500000 took: 1478.379823 ms | |
result futures: 499999500000 took: 274.371843 ms | |
result futures: 499999500000 took: 390.000957 ms | |
result futures: 499999500000 took: 247.929816 ms | |
result futures: 499999500000 took: 240.096408 ms | |
result futures: 499999500000 took: 219.66959 ms | |
result futures: 499999500000 took: 203.490966 ms | |
result futures: 499999500000 took: 223.054255 ms | |
result futures: 499999500000 took: 211.741709 ms | |
result futures: 499999500000 took: 212.549607 ms |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment