Skip to content

Commit fac138c

Browse files
authored
#45 - Two sided performance test for merge (#114)
This PR extends `measureSequenceThroughput` to take two outputs so functions like merge/ zip etc can be tested by both sides.
1 parent a8bba84 commit fac138c

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

Tests/AsyncAlgorithmsTests/Performance/TestThroughput.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ import AsyncAlgorithms
1515
#if canImport(Darwin)
1616
final class TestThroughput: XCTestCase {
1717
func test_chain2() async {
18-
await measureSequenceThroughput(output: 1) {
19-
chain($0, [].async)
18+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2) {
19+
chain($0, $1)
2020
}
2121
}
2222
func test_chain3() async {
23-
await measureSequenceThroughput(output: 1) {
24-
chain($0, [].async, [].async)
23+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2, thirdOutput: 3) {
24+
chain($0, $1, $2)
2525
}
2626
}
2727
func test_compacted() async {
@@ -40,13 +40,13 @@ final class TestThroughput: XCTestCase {
4040
}
4141
}
4242
func test_merge2() async {
43-
await measureSequenceThroughput(output: 1) {
44-
merge($0, (0..<10).async)
43+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2) {
44+
merge($0, $1)
4545
}
4646
}
4747
func test_merge3() async {
48-
await measureSequenceThroughput(output: 1) {
49-
merge($0, (0..<10).async, (0..<10).async)
48+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2, thirdOutput: 3) {
49+
merge($0, $1, $2)
5050
}
5151
}
5252
func test_removeDuplicates() async {
@@ -55,13 +55,13 @@ final class TestThroughput: XCTestCase {
5555
}
5656
}
5757
func test_zip2() async {
58-
await measureSequenceThroughput(output: 1) {
59-
zip($0, Indefinite(value: 2).async)
58+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2) {
59+
zip($0, $1)
6060
}
6161
}
6262
func test_zip3() async {
63-
await measureSequenceThroughput(output: 1) {
64-
zip($0, Indefinite(value: 2).async, Indefinite(value: 3).async)
63+
await measureSequenceThroughput(firstOutput: 1, secondOutput: 2, thirdOutput: 3) {
64+
zip($0, $1, $2)
6565
}
6666
}
6767
}

Tests/AsyncAlgorithmsTests/Performance/ThroughputMeasurement.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,57 @@ extension XCTestCase {
8787
}
8888
}
8989

90+
public func measureSequenceThroughput<S: AsyncSequence, Output>(firstOutput: @autoclosure () -> Output, secondOutput: @autoclosure () -> Output, _ sequenceBuilder: (InfiniteAsyncSequence<Output>, InfiniteAsyncSequence<Output>) -> S) async where S: Sendable {
91+
let metric = _ThroughputMetric()
92+
let sampleTime: Double = 0.1
93+
94+
measure(metrics: [metric]) {
95+
let firstInfSeq = InfiniteAsyncSequence(value: firstOutput(), duration: sampleTime)
96+
let secondInfSeq = InfiniteAsyncSequence(value: secondOutput(), duration: sampleTime)
97+
let seq = sequenceBuilder(firstInfSeq, secondInfSeq)
98+
99+
let exp = self.expectation(description: "Finished")
100+
let iterTask = Task<Int, Error> {
101+
var eventCount = 0
102+
for try await _ in seq {
103+
eventCount += 1
104+
}
105+
metric.eventCount = eventCount
106+
exp.fulfill()
107+
return eventCount
108+
}
109+
usleep(UInt32(sampleTime * Double(USEC_PER_SEC)))
110+
iterTask.cancel()
111+
self.wait(for: [exp], timeout: sampleTime * 2)
112+
}
113+
}
114+
115+
public func measureSequenceThroughput<S: AsyncSequence, Output>(firstOutput: @autoclosure () -> Output, secondOutput: @autoclosure () -> Output, thirdOutput: @autoclosure () -> Output, _ sequenceBuilder: (InfiniteAsyncSequence<Output>, InfiniteAsyncSequence<Output>, InfiniteAsyncSequence<Output>) -> S) async where S: Sendable {
116+
let metric = _ThroughputMetric()
117+
let sampleTime: Double = 0.1
118+
119+
measure(metrics: [metric]) {
120+
let firstInfSeq = InfiniteAsyncSequence(value: firstOutput(), duration: sampleTime)
121+
let secondInfSeq = InfiniteAsyncSequence(value: secondOutput(), duration: sampleTime)
122+
let thirdInfSeq = InfiniteAsyncSequence(value: thirdOutput(), duration: sampleTime)
123+
let seq = sequenceBuilder(firstInfSeq, secondInfSeq, thirdInfSeq)
124+
125+
let exp = self.expectation(description: "Finished")
126+
let iterTask = Task<Int, Error> {
127+
var eventCount = 0
128+
for try await _ in seq {
129+
eventCount += 1
130+
}
131+
metric.eventCount = eventCount
132+
exp.fulfill()
133+
return eventCount
134+
}
135+
usleep(UInt32(sampleTime * Double(USEC_PER_SEC)))
136+
iterTask.cancel()
137+
self.wait(for: [exp], timeout: sampleTime * 2)
138+
}
139+
}
140+
90141
public func measureSequenceThroughput<S: AsyncSequence, Source: AsyncSequence>( source: Source, _ sequenceBuilder: (Source) -> S) async where S: Sendable, Source: Sendable {
91142
let metric = _ThroughputMetric()
92143
let sampleTime: Double = 0.1

0 commit comments

Comments
 (0)