From 6f2bb8d6f81a0047a46934a583208f77400f7c33 Mon Sep 17 00:00:00 2001 From: Paul Flynn Date: Mon, 1 Jul 2024 18:54:22 -0400 Subject: [PATCH] Add benchmark testing to swift workflow This update restructures the testing process in the swift workflow by enabling code coverage during testing. Additionally, a new benchmarking step has been added. A new benchmarking script, Benchmark.swift, has also been created to specify and run the benchmarks. --- .github/workflows/swift.yml | 8 ++--- OpenTDFKitTests/Benchmark.swift | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 OpenTDFKitTests/Benchmark.swift diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 7454093..47f4d25 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -11,9 +11,7 @@ on: jobs: build: - runs-on: macos-latest - steps: - uses: actions/checkout@v4 - uses: maxim-lobanov/setup-xcode@v1 @@ -21,5 +19,7 @@ jobs: xcode-version: latest-stable - name: Build run: swift build -v - - name: Run tests - run: swift test -v + - name: Test + run: swift test --enable-code-coverage -v + - name: Benchmark + run: swift OpenTDFKitTests/Benchmark.swift diff --git a/OpenTDFKitTests/Benchmark.swift b/OpenTDFKitTests/Benchmark.swift new file mode 100644 index 0000000..eaa633c --- /dev/null +++ b/OpenTDFKitTests/Benchmark.swift @@ -0,0 +1,55 @@ +import Foundation + +public struct Benchmark { + let name: String + let operation: () -> Void + let iterations: Int + + public init(name: String, iterations: Int = 1000, operation: @escaping () -> Void) { + self.name = name + self.iterations = iterations + self.operation = operation + } + + public func run() -> (name: String, averageTime: Double) { + var totalTime: Double = 0 + + for _ in 1...iterations { + let start = DispatchTime.now() + operation() + let end = DispatchTime.now() + + let nanoTime = Double(end.uptimeNanoseconds - start.uptimeNanoseconds) + totalTime += nanoTime / 1_000_000_000 // Convert to seconds + } + + let averageTime = totalTime / Double(iterations) + return (name, averageTime) + } +} + +public func runBenchmarks(_ benchmarks: [Benchmark]) { + print("Running \(benchmarks.count) benchmarks...") + print("-----------------------------") + + for benchmark in benchmarks { + let result = benchmark.run() + print("\(result.name): \(result.averageTime) seconds (average over \(benchmark.iterations) iterations)") + } +} + +// Example usage: +let benchmarks = [ + Benchmark(name: "Array Sorting") { + var arr = (1...1000).map { _ in Int.random(in: 1...1000) } + arr.sort() + }, + Benchmark(name: "String Concatenation", iterations: 10000) { + var str = "" + for _ in 1...100 { + str += "Hello, World! " + } + } +] + +runBenchmarks(benchmarks)