Hi, why `Delay` use millis time(scheduleResumeAfte...
# coroutines
m
Hi, why
Delay
use millis time(scheduleResumeAfterDelay) instead of more accurate
Duration
? For now there is no way to pass Duration to UI dispatcher which is accurate, i.e don't make errors with rounding 😞
đŸ«ą 1
j
What is more accurate about Duration?
Ahh I see, it's got nano seconds
l
Probably historical reasons, and limitation of some target platforms? Which platform do you want to use nanoseconds level delay on?
m
@louiscad I'm generally concerned with the JVM right now. I have to write UI Dispatcher with similar mechanizm to the Looper from Android, however it turned out that for each call I have always unnecessary overhead of doing things by 1-2ms(thanks to the rounding). Even with an simple while loop that consumes coroutines. That's why I wanted to switch to nanoseconds. It would be really helpfull if Duration was passed in Delay instead of Long. For this moment I managed simply by writing an alternative to delay(), something like delayNano() but well it looks hacky to use it instead delay() 🙂
And this problem is on all UI Dispatchers, such as Android, swing, javafx. With the simplest program where should be nanoseconds of difference in execution, there will be often 1-2ms difference, Keep in mind that even small 1-2ms has a big impact on refresh rate of all graphics things(At 60 fps, that's almost 10% latency).
g
On Android it cannot be more precise than 1ms, because Handler API also ms precision, it will be a bit more precise of course with duration thanks to rounding, but you cannot really rely on better precision anyway
m
@gildor sadly I can't agree, 1-2ms unnecessary overhead is a lot for graphics programmers. For UI dispatcher(which runs on 1 thread) I can predict when it will execute, and how long it will take to execute, In implementation, it is a simple queue with execution time that run in main while loop. For my project 1-2ms give a lot(I have 1000 fps) which is already unnecessary delay by 50%. Also android isn't really indicator of quality(anyone who has ever analyzed deeply its code knows this). Btw, there is code in old android that uses nanoseconds: https://android.googlesource.com/platform/frameworks/native/+/android-4.2.2_r1/include/utils/Looper.h I wonder why they changed it.
l
Summoning @Vsevolod Tolstopyatov [JB] on that one, he might have insights about that shortcoming.
g
@MichaƂ Kalinowski You cannot agree on what? public Handler java API has only milliseconds: https://developer.android.com/reference/android/os/Handler So as result you cannot schedule it with higher precision on main thread I don’t say that it indicator of quality, nothing is indicator. It’s just the most popular OS in the world I also think that it makes sense to have higher precision. The reason why it has no support of Duration is simply because Duration didn’t exist when this API was added, but it’s actually quite a good case for generic API
m
@gildor I can't agree that you shouldn't rely on better precision. Maybe we misunderstood I wasn't referring specifically to android here. But as far as Android is concerned, the Choreographers are "some" sort of replacement for Handler, so you can have precision in nanoseconds. Android Dispatcher has a method for it called awaitFrame().
g
I never said this, just pointed out that it just doesn’t work on all platforms at least
m
yep, simple misunderstanding ;)
g
also you right that there APIs intended to use with animation, but those are not connected to delay and delay shouldn’t be really used for this use case, this why awaitFrame exists, but it uses android Choreographer API, not Handler, which used for dispatching tasks on main thread. Again, I’m not against more precision for delay, but delay is never a solution for integration with rendering pipeline anyway, every platform has own rendering implementation which is not necessary relies on standard delay/scheduling mechanism
Btw Choreographer has no nanoseconds API, delay is still in milliseconds, it just adjusted by frame
g
But you cannot it schedule by nanoseconds, only by millisecons, this
long frameTimeNanos
is to tell you exact frame time rendering from callback You cannot tell it “do this in x nanoseconds + frame rendering” only “do this in x milliseconds + frame rendering
m
yep, that's not replacement for the handler, Choreographer with nanoseconds need to rely entirely on frameTime(some sort of deltaTime thanks to which we can get next frame). This was just an example that there are mechanisms in the Androids UI which can depends on nanoseconds
v
Most of
kotlinx.coroutines
functions provide
fooMs: Long
instead of
Duration
simply because such API predates existence of
Duration
class. We have a preliminary decision that all new time-related API will only accept
Duration
and not
Long
, but we are not sure we are ready to migrate existing users from it (well, maybe until https://youtrack.jetbrains.com/issue/KT-54106 is implemented). Regarding the precision — yes, it could’ve been better in general (i.e. the default
Delay
implementation delegates the precision to
Thread.sleep(ms, ns)
and bounded by the underlying OS precision). For UI systems (e.g. Android, JavaFx, Swing), most of the underlying API accepts
millis: Long
anyway, and probably that’s the reason this topic was never actively discussed