Skip to content
This repository was archived by the owner on Feb 2, 2025. It is now read-only.

Commit e02d8b6

Browse files
author
Alex Belozierov
committed
- improved await() performance
1 parent bb23886 commit e02d8b6

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

Sources/SwiftCoroutine/Coroutine/SharedCoroutineDispatcher/SharedCoroutine.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ internal final class SharedCoroutine {
2222
private var environment: UnsafeMutablePointer<CoroutineContext.SuspendData>!
2323
private var stackBuffer: StackBuffer!
2424
private var isCanceled = 0
25+
private var awaitTag = 0
2526

2627
internal init(dispatcher: SharedCoroutineDispatcher, queue: SharedCoroutineQueue, scheduler: CoroutineScheduler) {
2728
self.dispatcher = dispatcher
@@ -96,9 +97,13 @@ extension SharedCoroutine: CoroutineProtocol {
9697
internal func await<T>(_ callback: (@escaping (T) -> Void) -> Void) throws -> T {
9798
if isCanceled == 1 { throw CoroutineError.canceled }
9899
state = .suspending
99-
var result: T!, resultState = 0
100+
let tag = awaitTag
101+
var result: T!
100102
callback { value in
101-
if atomicExchange(&resultState, with: 1) == 1 { return }
103+
while true {
104+
guard self.awaitTag == tag else { return }
105+
if atomicCAS(&self.awaitTag, expected: tag, desired: tag + 1) { break }
106+
}
102107
result = value
103108
self.resumeIfSuspended()
104109
}

SwiftCoroutine.xcodeproj/xcshareddata/xcbaselines/F8CD25A920199D1000952299.xcbaseline/DEB0EA3A-457C-4029-95F2-69E53CE6D25D.plist

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@
1919
</dict>
2020
<key>CoFutureAwaitTests</key>
2121
<dict>
22+
<key>testAbc()</key>
23+
<dict>
24+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
25+
<dict>
26+
<key>baselineAverage</key>
27+
<real>0.50477</real>
28+
<key>baselineIntegrationDisplayName</key>
29+
<string>Local Baseline</string>
30+
</dict>
31+
</dict>
32+
<key>testAwaitMeasure()</key>
33+
<dict>
34+
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
35+
<dict>
36+
<key>baselineAverage</key>
37+
<real>0.056</real>
38+
<key>baselineIntegrationDisplayName</key>
39+
<string>Local Baseline</string>
40+
</dict>
41+
</dict>
2242
<key>testMultipleAwaits()</key>
2343
<dict>
2444
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
@@ -44,7 +64,7 @@
4464
<key>com.apple.XCTPerformanceMetric_WallClockTime</key>
4565
<dict>
4666
<key>baselineAverage</key>
47-
<real>0.121</real>
67+
<real>0.0836</real>
4868
<key>baselineIntegrationDisplayName</key>
4969
<string>Local Baseline</string>
5070
</dict>

Tests/SwiftCoroutineTests/CoFutureTests/CoFutureAwaitTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ class CoFutureAwaitTests: XCTestCase {
4545
XCTAssertTrue(array.enumerated().allSatisfy { $0.element == $0.offset })
4646
array.deallocate()
4747
}
48+
49+
func testAwaitMeasure() {
50+
measure {
51+
ImmediateScheduler().startCoroutine {
52+
for index in 0..<100_000 {
53+
let _ = try Coroutine.await { $0(index) }
54+
}
55+
}
56+
}
57+
}
4858

4959
func testNestetAwaits() {
5060
let queue = DispatchQueue.global(qos: .userInteractive)

0 commit comments

Comments
 (0)