Skip to content

Commit

Permalink
fix(minor): Make setup/teardown hooks usable in Swift 6 mode (#312)
Browse files Browse the repository at this point in the history
Fixes #311

---------

Co-authored-by: ordo-ci <[email protected]>
  • Loading branch information
hassila and ordo-ci authored Feb 14, 2025
1 parent 2bb8a39 commit 8daf174
Show file tree
Hide file tree
Showing 28 changed files with 194 additions and 235 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/swift-linux-previous.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
os: [ubuntu-22.04]
swift: ["5.9", "5.10"]


Expand Down
10 changes: 9 additions & 1 deletion .github/workflows/swift-macos-previous.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ jobs:
fail-fast: false
matrix:
os: [macos-14]
swift: ["5.9", "5.10"]
xcode: ["15.2", "15.3"]
#swift: ["5.9", "5.10"]

runs-on: ${{ matrix.os }}

steps:
- uses: swift-actions/setup-swift@v2
if: ${{ false }}
with:
swift-version: ${{ matrix.swift }}
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ${{ matrix.xcode }}

- name: Homebrew Mac
if: ${{ runner.os == 'Macos' }}
Expand Down Expand Up @@ -49,3 +54,6 @@ jobs:
if [ -d Tests ]; then
swift test -c release --parallel
fi
- name: Setup tmate session
if: failure()
uses: mxschmitt/action-tmate@v3
4 changes: 2 additions & 2 deletions Benchmarks/Benchmarks/Basic/Basic+SetupTeardown.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ func sharedTeardown() {
}

func testSetUpTearDown() {
// Benchmark.setup = { print("Global setup hook")}
// Benchmark.setup = { print("Global setup hook")}
// Benchmark.setup = { 123 }
// Benchmark.teardown = { print("Global teardown hook") }
// Benchmark.teardown = { print("Global teardown hook") }

Benchmark("SetupTeardown",
configuration: .init(setup: sharedSetup, teardown: sharedTeardown)) { _ in
Expand Down
16 changes: 2 additions & 14 deletions Benchmarks/Benchmarks/Basic/BenchmarkRunner+Basic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,10 @@ import Glibc
// quiet swiftlint for now
extension BenchmarkRunner {}

let benchmarks = {
let benchmarks: @Sendable () -> Void = {
var thresholdTolerances: [BenchmarkMetric: BenchmarkThresholds]

if Benchmark.checkAbsoluteThresholds {
let absolute: BenchmarkThresholds.AbsoluteThresholds = [.p0: .microseconds(1),
.p25: .microseconds(1),
.p50: .microseconds(2_500),
.p75: .microseconds(1),
.p90: .microseconds(2),
.p99: .milliseconds(3),
.p100: .milliseconds(1)]

thresholdTolerances = [.wallClock: .init(absolute: absolute)]
} else {
thresholdTolerances = [.wallClock: .relaxed]
}
thresholdTolerances = [.wallClock: .relaxed]

Benchmark.defaultConfiguration = .init(warmupIterations: 0,
maxDuration: .seconds(1),
Expand Down
2 changes: 1 addition & 1 deletion Benchmarks/Benchmarks/DateTime/DateTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import Benchmark
import DateTime

let benchmarks = {
let benchmarks: @Sendable () -> Void = {
Benchmark.defaultConfiguration = .init(metrics: [.throughput, .wallClock, .instructions] + .arc,
warmupIterations: 10,
scalingFactor: .kilo,
Expand Down
2 changes: 1 addition & 1 deletion Benchmarks/Benchmarks/Histogram/Histogram.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import Benchmark
import Histogram

let benchmarks = {
let benchmarks: @Sendable () -> Void = {
let metrics: [BenchmarkMetric] = [
.wallClock,
.throughput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Foundation
#error("Unsupported Platform")
#endif

let benchmarks = {
let benchmarks: @Sendable () -> Void = {
var thresholdTolerances: [BenchmarkMetric: BenchmarkThresholds]
let relative: BenchmarkThresholds.RelativeThresholds = [.p25: 25.0, .p50: 50.0, .p75: 75.0, .p90: 100.0, .p99: 101.0, .p100: 201.0]
let absolute: BenchmarkThresholds.AbsoluteThresholds = [.p75: 999, .p90: 1_000, .p99: 1_001, .p100: 2_001]
Expand Down
4 changes: 2 additions & 2 deletions Benchmarks/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.9
// swift-tools-version: 6.0

import class Foundation.ProcessInfo
import PackageDescription
Expand All @@ -8,7 +8,7 @@ let disableJemalloc = ProcessInfo.processInfo.environment["BENCHMARK_DISABLE_JEM

let package = Package(
name: "Benchmarks",
platforms: [.macOS(.v14), .iOS(.v17)],
platforms: [.macOS(.v15), .iOS(.v17)],
dependencies: [
.package(path: "../"),
.package(url: "https://github.com/ordo-one/package-datetime", .upToNextMajor(from: "1.0.1")),
Expand Down
2 changes: 0 additions & 2 deletions Plugins/BenchmarkCommandPlugin/Command+Helpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ public enum Grouping: String, CaseIterable {
case benchmark
}

#if swift(>=5.8)
@_documentation(visibility: internal)
#endif
public enum TimeUnits: String, CaseIterable {
case nanoseconds
case microseconds
Expand Down
20 changes: 9 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ There are [documentation available](https://swiftpackageindex.com/ordo-one/packa
```swift
import Benchmark

let benchmarks = {
let benchmarks : @Sendable () -> Void = {
Benchmark("Minimal benchmark") { benchmark in
// measure something here
}
Expand Down Expand Up @@ -159,6 +159,14 @@ Using [jmh.morethan.io](https://jmh.morethan.io)

<img width="1482" alt="image" src="https://user-images.githubusercontent.com/8501048/225313559-33014755-797f-4ddf-b536-24c1a618f271.png">

## Swift 6 support
The package supports Swift 6.0 benchmark targets as well as Swift 5.10 targets (for Swift 5.9 support, need to use version 1.28.0 exactly).

For Swift 6 targets, use the following signature for the benchmarks closure:
```swift
let benchmarks : @Sendable () -> Void = {
```

## Output

The default text output from Benchmark is oriented around [the five-number summary](https://en.wikipedia.org/wiki/Five-number_summary) percentiles, plus the last decile (`p90`) and the last percentile (`p99`) - it's thus a variation of a [seven-figure summary](https://en.wikipedia.org/wiki/Seven-number_summary) with the focus on the 'bad' end of results (as those are what we typically care about addressing).
Expand All @@ -168,16 +176,6 @@ This multi-modal nature of the latency measurements leads to the common statisti

Please see the [documentation for further details on percentiles](https://swiftpackageindex.com/ordo-one/package-benchmark/documentation/benchmark/aboutpercentiles).

## Swift 6 support
The package will be updated to be fully Swift 6 when 5.x support is dropped (planned to be when Swift 6.2 is released).

Workaround needed for Swift 6 targets, use the following signature for the benchmarks closure:
```swift
let benchmarks : @Sendable () -> Void = {
```

See https://github.com/ordo-one/package-benchmark/issues/258 for more details.

## API and file format stability
The API will be deemed stable as of `1.0.0` and follows semantical versioning for future releases.

Expand Down
5 changes: 1 addition & 4 deletions Sources/Benchmark/ARCStats/ARCStats.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
//

/// The ARC stats the ARCStatsProducer can provide
#if swift(>=5.8)
@_documentation(visibility: internal)
#endif

@_documentation(visibility: internal)
struct ARCStats {
var objectAllocCount: Int = 0 /// total number allocations, implicit retain
var retainCount: Int = 0 /// total number retains
Expand Down
8 changes: 8 additions & 0 deletions Sources/Benchmark/Benchmark+ConvenienceInitializers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ public extension Benchmark {
/// - configuration: Defines the settings that should be used for this benchmark
/// - closure: The actual benchmark closure that will be measured, this one takes one additional parameter
/// apart from the benchmark instance, which is the generic SetupResult type returned from the setup
/// - setup: A closure that will be run once before the benchmark iterations are run
/// - teardown: A closure that will be run once after the benchmark iterations are done
@discardableResult
convenience init?<SetupResult>(_ name: String,
configuration: Benchmark.Configuration = Benchmark.defaultConfiguration,
Expand All @@ -31,6 +33,8 @@ public extension Benchmark {
/// - configuration: Defines the settings that should be used for this benchmark
/// - closure: The actual `async` benchmark closure that will be measured, this one takes one additional parameter
/// apart from the benchmark instance, which is the generic SetupResult type returned from the setup
/// - setup: A closure that will be run once before the benchmark iterations are run
/// - teardown: A closure that will be run once after the benchmark iterations are done
@discardableResult
convenience init?<SetupResult>(_ name: String,
configuration: Benchmark.Configuration = Benchmark.defaultConfiguration,
Expand All @@ -56,6 +60,8 @@ public extension Benchmark {
/// - configuration: Defines the settings that should be used for this benchmark
/// - closure: The actual throwing benchmark closure that will be measured, this one takes one additional parameter
/// apart from the benchmark instance, which is the generic SetupResult type returned from the setup
/// - setup: A closure that will be run once before the benchmark iterations are run
/// - teardown: A closure that will be run once after the benchmark iterations are done
@discardableResult
convenience init?<SetupResult>(_ name: String,
configuration: Benchmark.Configuration = Benchmark.defaultConfiguration,
Expand Down Expand Up @@ -83,6 +89,8 @@ public extension Benchmark {
/// - configuration: Defines the settings that should be used for this benchmark
/// - closure: The actual async throwing benchmark closure that will be measured, this one takes one additional parameter
/// apart from the benchmark instance, which is the generic SetupResult type returned from the setup
/// - setup: A closure that will be run once before the benchmark iterations are run
/// - teardown: A closure that will be run once after the benchmark iterations are done
@discardableResult
convenience init?<SetupResult>(_ name: String,
configuration: Benchmark.Configuration = Benchmark.defaultConfiguration,
Expand Down
Loading

0 comments on commit 8daf174

Please sign in to comment.