Adam Miskiewicz
12/04/2024, 5:34 PMasync
) for every field in a GraphQL query (which could have >5k with very large queries), the overhead -- specifically, seemingly, in handling of CoroutineContext (and even worse, ThreadLocalElement's...) is significant (I see things like CombinedContext.fold
taking up 20% of total CPU). I'm wondering if folks have done any work on perf in this area, if this is known, etc? What's the "recommended" upper bound of how many coroutines to create? It's totally reasonable to say "well nothing's free!" -- it makes sense why you can't just create infinite coroutines and expect zero cost. But I haven't seen much published on this, so I'm wondering if people have had any similar experiences they'd like to share.Dariusz Kuc
12/04/2024, 8:27 PMgraphql-java
were wrapping everything in completable futures. They fixed that in v22. Might be related.kevin.cianfarini
12/04/2024, 9:23 PMAdam Miskiewicz
12/04/2024, 9:23 PMAdam Miskiewicz
12/04/2024, 9:24 PMDariusz Kuc
12/04/2024, 9:24 PMDariusz Kuc
12/04/2024, 9:25 PMkevin.cianfarini
12/04/2024, 9:25 PMkevin.cianfarini
12/04/2024, 9:26 PMkevin.cianfarini
12/04/2024, 9:27 PMAdam Miskiewicz
12/04/2024, 9:28 PMkevin.cianfarini
12/04/2024, 9:29 PMkevin.cianfarini
12/04/2024, 9:31 PMkevin.cianfarini
12/04/2024, 9:31 PMlaunch
and not async
but I imagine a lot of the machinery for them is similar.kevin.cianfarini
12/04/2024, 9:33 PMCoroutineContext.fold
is defined in the stdlib and not in kotlinx.Dariusz Kuc
12/04/2024, 9:35 PMcoroutines being cheap
well they are "cheap" compared to threads (also lighter than virtual threads) but there is always some costkevin.cianfarini
12/04/2024, 9:36 PMDariusz Kuc
12/04/2024, 9:38 PMAlso, I'm writing my own impl.
side question 🙂 somewhat curious about that as well ⬆️ but that probably is a better conversation for #CKD2KL89G channel 🙂kevin.cianfarini
12/04/2024, 9:44 PMCoroutineContext.fold
, and perhaps that’s because your coroutines are switching contexts a lot? Is that something you can try to limit?Dariusz Kuc
12/04/2024, 9:45 PMAdam Miskiewicz
12/04/2024, 9:45 PMIs that something you can try to limit?It's really any coroutine creation that causes the context folding. Even if you use fancy "undispatched" coroutines, which don't switch threads, it still does the fold operation.
Adam Miskiewicz
12/04/2024, 9:46 PMkevin.cianfarini
12/04/2024, 9:46 PMAdam Miskiewicz
12/04/2024, 9:47 PMAdam Miskiewicz
12/04/2024, 9:47 PMYeah that makes sense, each async is creating a new child job that needs to be put into the context. So folding contexts is probably necessary. (edited)exactly.
Dariusz Kuc
12/04/2024, 9:47 PMAdam Miskiewicz
12/04/2024, 9:48 PMasync { }
for each one, have nice suspend functions for all the field handlingAdam Miskiewicz
12/04/2024, 9:48 PMAdam Miskiewicz
12/04/2024, 9:48 PMAdam Miskiewicz
12/04/2024, 9:48 PMkevin.cianfarini
12/04/2024, 9:48 PMAdam Miskiewicz
12/04/2024, 9:49 PMAdam Miskiewicz
12/04/2024, 9:50 PMkevin.cianfarini
12/04/2024, 9:50 PMAdam Miskiewicz
12/04/2024, 9:50 PMkevin.cianfarini
12/04/2024, 9:51 PMAdam Miskiewicz
12/04/2024, 9:51 PMJP Sugarbroad
12/04/2024, 9:51 PMCoroutineStart.UNDISPATCHED
, but be careful.Adam Miskiewicz
12/04/2024, 9:51 PMJP Sugarbroad
12/04/2024, 9:51 PMJP Sugarbroad
12/04/2024, 9:52 PMJP Sugarbroad
12/04/2024, 9:52 PMJob
machinery looked pretty heavyweight when I last checked.kevin.cianfarini
12/04/2024, 9:53 PMAdam Miskiewicz
12/04/2024, 9:53 PMJP Sugarbroad
12/04/2024, 9:54 PMAdam Miskiewicz
12/04/2024, 9:54 PMscopedFuture
call (which is kind of just a wrapper around async, but propagates coroutineContext through Java-land) is spent manipulating contextAdam Miskiewicz
12/04/2024, 9:54 PMJP Sugarbroad
12/04/2024, 9:55 PMJP Sugarbroad
12/04/2024, 9:57 PMCopyableThreadContextElement
stuff.Adam Miskiewicz
12/04/2024, 9:58 PMThreadLocalCoroutineContextManager
is something that lets me hold the coroutineContext inside of a thread local, so that I can reference the coroutinecontext from a non-suspend function.Adam Miskiewicz
12/04/2024, 9:59 PMJP Sugarbroad
12/04/2024, 9:59 PMAdam Miskiewicz
12/04/2024, 10:00 PMAdam Miskiewicz
12/04/2024, 10:01 PMAdam Miskiewicz
12/04/2024, 10:01 PMAdam Miskiewicz
12/04/2024, 10:01 PMkevin.cianfarini
12/04/2024, 10:02 PMJP Sugarbroad
12/04/2024, 10:02 PMDispatchers.Unconfined
Adam Miskiewicz
12/04/2024, 10:03 PMAdam Miskiewicz
12/04/2024, 10:03 PMJP Sugarbroad
12/04/2024, 10:03 PMCopyableThreadContextElement
is. Those things are expensive.kevin.cianfarini
12/04/2024, 10:03 PMkevin.cianfarini
12/04/2024, 10:03 PMJP Sugarbroad
12/04/2024, 10:04 PMJP Sugarbroad
12/04/2024, 10:09 PMthreadContextElements
could use to be optimized, perhaps, but it looks like the intention is that `DispatchedContinuation`s don't get created super-often.JP Sugarbroad
12/04/2024, 10:10 PMSamuel Vazquez
12/04/2024, 10:18 PMkevin.cianfarini
12/04/2024, 10:47 PMkevin.cianfarini
12/04/2024, 10:48 PMAdam Miskiewicz
12/04/2024, 10:48 PMAdam Miskiewicz
12/04/2024, 10:48 PMkevin.cianfarini
12/04/2024, 10:50 PMkevin.cianfarini
12/04/2024, 10:51 PMkevin.cianfarini
12/04/2024, 10:51 PMkevin.cianfarini
12/04/2024, 10:52 PMkevin.cianfarini
12/04/2024, 10:52 PMAdam Miskiewicz
12/04/2024, 10:52 PMAdam Miskiewicz
12/04/2024, 10:53 PMAdam Miskiewicz
12/04/2024, 10:53 PMAdam Miskiewicz
12/04/2024, 10:54 PMAdam Miskiewicz
12/04/2024, 10:54 PMAdam Miskiewicz
12/04/2024, 10:54 PMAdam Miskiewicz
12/04/2024, 10:54 PMSamuel Vazquez
12/04/2024, 10:54 PMAdam Miskiewicz
12/04/2024, 10:54 PMAdam Miskiewicz
12/04/2024, 10:55 PMAdam Miskiewicz
12/04/2024, 10:55 PMSamuel Vazquez
12/04/2024, 10:57 PMSamuel Vazquez
12/05/2024, 1:17 AMephemient
12/08/2024, 10:59 AM.flatMapMerge()
that process an unbounded number of flows but only up to DEFAULT_CONCURRENCY concurrently at a time