Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin Coroutines can dispatch on LOOM threads #74

Closed
apatrida opened this issue Jan 15, 2023 · 1 comment · Fixed by #75
Closed

Kotlin Coroutines can dispatch on LOOM threads #74

apatrida opened this issue Jan 15, 2023 · 1 comment · Fixed by #75
Labels
enhancement New feature or request

Comments

@apatrida
Copy link

apatrida commented Jan 15, 2023

Nice article!

Have you considered dispatching Kotlin coroutines onto Loom VirtualThreads?

Example idea:
https://kt.academy/article/dispatcher-loom

Here just create a simple dispatcher...

val Dispatchers.LOOM: CoroutineDispatcher
    get() = Executors.newVirtualThreadPerTaskExecutor().asCoroutineDispatcher()

And change your async { ... } call to use this dispatcher as

async(Dispatchers.LOOM) { ... }

Note your controlTest can have both a Thread { ... } version and a Thread.startVirtualThread { ... } version since nothing stops Kotlin from using LOOM virtual threads directly.

A lot of this code in the samples can be shared between them as Kotlin has no problem accessing Java classes, and most concepts in Kotlin are readable from Java as well. Unless you are worried about performance of basic code between the two, the total codebase could be reduced.

sample run-local with Java, Kotlin coroutines, Kotlin w/Loom async coroutines

Time Method Time Complexity Space Complexity Repetitions Java Duration Kotlin Duration Kotlin-Loom Duration Machine
2023-01-15T15:03:16.502528 wait0Nanos - Wait 0 Nanos - Running - Yielding - Virtual Thread n/a n/a 2 8 -1 -1 Prototype
2023-01-15T15:03:16.508950 wait100Mills - Wait 100 Mills - Running - Parking - Yield - Virtual Thread n/a n/a 2 101 -1 -1 Prototype
2023-01-15T15:03:16.509022 saveWordsNio - Write to 1 file - Yield - Virtual Thread n/a n/a 2 112 -1 -1 Prototype
2023-01-15T15:03:16.509055 saveWordsNio - Write to 1 file - Pinning - Yield - Virtual Thread n/a n/a 2 222 -1 -1 Prototype
2023-01-15T15:03:16.509082 findAllUniqueWords - All Unique Words n/a n/a 10000 1464 2839 2292 Prototype
2023-01-15T15:03:16.509110 findAllUniqueWordsWithCount - All Words with count n/a n/a 10000 1031 2081 1261 Prototype
2023-01-15T15:03:16.509137 revertText - Reverted Text O(n) O(1) 10000 324 866 594 Prototype
2023-01-15T15:03:16.509170 contentSplitIterateSubtractAndSum - Double iteration of an array of words O(n^2) O(1) 10000 373 1496 1120 Prototype
2023-01-15T15:03:16.509198 repetitionCount - Repetition count O(n^2) O(n) 10000 2238 2734 721 Prototype
2023-01-15T15:03:16.509223 createAvlTree - Create AVL Tree O(log n) O(n) 10000 1197 749 178 Prototype
2023-01-15T15:03:16.509249 findPrimeSecret - Secret word in Sieve of Eratosthenes O(n * log(log n)) O(n) 10000 556 1632 519 Prototype
2023-01-15T15:03:16.509277 createSplayTree - Create Splay Tree O(log n) O(n) 10000 153 604 215 Prototype
2023-01-15T15:03:16.509303 quickSort - Quick sort O(n * log n) O(log n) 10000 1057 3616 2815 Prototype
2023-01-15T15:03:16.509334 makeTextFromWordFlow - Make text from word Flow n/a n/a 10000 889 519 147 Prototype
2023-01-15T15:03:16.509367 createIntersectionWordList - Intersection Text Algorithm O(n) O(n) 10000 83 956 482 Prototype
2023-01-15T15:03:16.509397 controlTest - N/A n/a n/a 10000 742 596 722 Prototype
2023-01-15T15:03:16.509424 generalTest - N/A n/a n/a 10000 182 59 173 Prototype
2023-01-15T15:03:16.509450 findAllUniqueWords - wait0Nanos n/a n/a 2 -1 12 21 Prototype
2023-01-15T15:03:16.509475 controlTest-Loom - N/A n/a n/a 10000 -1 -1 10 Prototype

That last controlTest-Loom is just Kotlin controlTest changed to use VirtualThread

@DelicateCoroutinesApi
        suspend fun controlTestWithVirtualThreads(repeats: Int) {
            log.info("----====>>>> Starting LOOM controlTest <<<<====----")
            val startTimeT = LocalDateTime.now()
            val aiThread = AtomicInteger(0)
            withContext(Dispatchers.IO) {
                (1..repeats).map {
                    Thread.startVirtualThread { aiThread.getAndIncrement() }
                }.forEach { it.join() }
            }
            val endTimeT = LocalDateTime.now()
            log.info("Imma be the main Thread")
            log.info(aiThread.get().toString())
            log.info("It took me {} ms to finish", Duration.between(startTimeT, endTimeT).toMillis())     }
@jesperancinha
Copy link
Owner

Hi @apatrida, thank you so much for your contribution. I didn't knew that it was possible to dispatch coroutines onto Loom Virtual Threads. It is indeed a good addition to this repository. Thank you for letting me know!

@jesperancinha jesperancinha added the enhancement New feature or request label Jan 16, 2023
@jesperancinha jesperancinha linked a pull request Jan 16, 2023 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants