Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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()
- }
- }
Add Comment
Please, Sign In to add comment