File tree Expand file tree Collapse file tree
Sources/JavaScriptEventLoop Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -20,10 +20,8 @@ extension JavaScriptEventLoop {
2020 return performanceNow!. now ( this: performanceNow!. performance) . number!
2121 }
2222
23- func hasRun( since start: DrainInstant , for interval: Duration ) -> Bool {
24- let ( seconds, attoseconds) = interval. components
25- let intervalMilliseconds = Double ( seconds) * 1_000 + Double( attoseconds) / 1_000_000_000_000_000
26- return drainClockNow ( ) - start >= intervalMilliseconds
23+ func drainElapsed( since start: DrainInstant ) -> Duration {
24+ . milliseconds( drainClockNow ( ) - start)
2725 }
2826 #else
2927 typealias DrainInstant = ContinuousClock . Instant
@@ -32,8 +30,8 @@ extension JavaScriptEventLoop {
3230 ContinuousClock . now
3331 }
3432
35- func hasRun ( since start: DrainInstant , for interval : Duration ) -> Bool {
36- start. duration ( to: . now) >= interval
33+ func drainElapsed ( since start: DrainInstant ) -> Duration {
34+ start. duration ( to: . now)
3735 }
3836 #endif
3937
Original file line number Diff line number Diff line change @@ -45,6 +45,10 @@ extension JavaScriptEventLoop {
4545
4646 // The clock is only read while `yieldInterval` is set.
4747 var start : DrainInstant ? = yieldInterval == nil ? nil : drainClockNow ( )
48+ // A clock read costs more than a small job. Read it every `clockStride` jobs, and double
49+ // the stride (up to 256) while the drain is far from the interval.
50+ var clockStride = 1
51+ var jobsUntilClockRead = 1
4852 while let job = self . claimNextFromQueue ( ) {
4953 #if compiler(>=5.9)
5054 job. runSynchronously ( on: self . asUnownedSerialExecutor ( ) )
@@ -54,11 +58,18 @@ extension JavaScriptEventLoop {
5458
5559 if let yieldInterval, queueState. headJob != nil {
5660 if let start {
57- if hasRun ( since: start, for: yieldInterval) {
61+ jobsUntilClockRead -= 1
62+ if jobsUntilClockRead > 0 { continue }
63+ let elapsed = drainElapsed ( since: start)
64+ if elapsed >= yieldInterval {
5865 // Keep `isSpinning` set so new jobs wait for the continuation.
5966 queueHostTask { self . runAllJobs ( ) }
6067 return
6168 }
69+ if elapsed * 4 < yieldInterval {
70+ clockStride = min ( clockStride * 2 , 256 )
71+ }
72+ jobsUntilClockRead = clockStride
6273 } else {
6374 start = drainClockNow ( )
6475 }
You can’t perform that action at this time.
0 commit comments