From 3631941b65a5991e6040a62bdbd2ce237c057b65 Mon Sep 17 00:00:00 2001 From: Jay Herron Date: Sat, 18 Apr 2026 14:17:54 -0600 Subject: [PATCH] feat: Adds Benchmarks --- .gitignore | 2 + .../Benchmarks/DataLoaderBenchmarks.swift | 99 +++++++++++++++ Benchmarks/Package.resolved | 113 ++++++++++++++++++ Benchmarks/Package.swift | 27 +++++ 4 files changed, 241 insertions(+) create mode 100644 Benchmarks/Benchmarks/DataLoaderBenchmarks.swift create mode 100644 Benchmarks/Package.resolved create mode 100644 Benchmarks/Package.swift diff --git a/.gitignore b/.gitignore index 29cc641..9ee4a1d 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,5 @@ iOSInjectionProject/ # VS Code .vscode/ + +.DS_Store diff --git a/Benchmarks/Benchmarks/DataLoaderBenchmarks.swift b/Benchmarks/Benchmarks/DataLoaderBenchmarks.swift new file mode 100644 index 0000000..d89994d --- /dev/null +++ b/Benchmarks/Benchmarks/DataLoaderBenchmarks.swift @@ -0,0 +1,99 @@ +import Benchmark +import NIO +import AsyncDataLoader +import DataLoader + +let eventLoopGroup = MultiThreadedEventLoopGroup.singleton + +let benchmarks: @Sendable () -> Void = { + + // MARK: Async + + let nonBatchingLoader = DataLoader( + options: .init( + batchingEnabled: true, + cachingEnabled: false, + ) + ) { keys in + keys.map { DataLoaderValue.success($0) } + } + + let batchingLoader = DataLoader( + options: .init( + batchingEnabled: true, + cachingEnabled: false, + maxBatchSize: 10 + ) + ) { keys in + keys.map { DataLoaderValue.success($0) } + } + + Benchmark("loadNonBatching") { _ in + try await withThrowingTaskGroup { group in + for i in (0..<1_000) { + group.addTask { + try await nonBatchingLoader.load(key: i) + } + } + try await group.waitForAll() + } + } + + Benchmark("loadBatching") { _ in + try await withThrowingTaskGroup { group in + for i in (0..<1_000) { + group.addTask { + try await batchingLoader.load(key: i) + } + } + try await group.waitForAll() + } + } + + Benchmark("loadBatchingMany") { _ in + let result = try await batchingLoader.loadMany(keys: Array(0..<1_000)) + } + + // MARK: NIO + + let nioNonBatchingLoader = DataLoader( + options: .init( + batchingEnabled: true, + cachingEnabled: false, + ) + ) { keys in + return eventLoopGroup.next().makeSucceededFuture( + keys.map { DataLoaderFutureValue.success($0) } + ) + } + + let nioBatchingLoader = DataLoader( + options: .init( + batchingEnabled: true, + cachingEnabled: false, + maxBatchSize: 10 + ) + ) { keys in + return eventLoopGroup.next().makeSucceededFuture( + keys.map { DataLoaderFutureValue.success($0) } + ) + } + + Benchmark("nioLoadNonBatching") { _ in + let futures = try (0..<1_000).map { i in + try nioNonBatchingLoader.load(key: i, on: eventLoopGroup.next()) + } + let result = try EventLoopFuture.whenAllSucceed(futures, on: eventLoopGroup.next()).wait() + } + + Benchmark("nioLoadBatching") { _ in + let futures = try (0..<1_000).map { i in + try nioBatchingLoader.load(key: i, on: eventLoopGroup.next()) + } + let result = try EventLoopFuture.whenAllSucceed(futures, on: eventLoopGroup.next()).wait() + } + + Benchmark("nioLoadBatchingMany") { _ in + let result = try nioBatchingLoader.loadMany(keys: Array(0..<1_000), on: eventLoopGroup.next()).wait() + } +} diff --git a/Benchmarks/Package.resolved b/Benchmarks/Package.resolved new file mode 100644 index 0000000..ff8ee56 --- /dev/null +++ b/Benchmarks/Package.resolved @@ -0,0 +1,113 @@ +{ + "pins" : [ + { + "identity" : "async-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/adam-fowler/async-collections", + "state" : { + "revision" : "726af96095a19df6b8053ddbaed0a727aa70ccb2", + "version" : "0.1.0" + } + }, + { + "identity" : "hdrhistogram-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/HdrHistogram/hdrhistogram-swift.git", + "state" : { + "revision" : "93a1618c8aa20f6a521a9da656a3e0591889e9dc", + "version" : "0.1.3" + } + }, + { + "identity" : "package-benchmark", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/package-benchmark", + "state" : { + "revision" : "acfd97b98f5a40d963c89437e1cfaeab8ef10bf9", + "version" : "1.29.7" + } + }, + { + "identity" : "package-jemalloc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/package-jemalloc.git", + "state" : { + "revision" : "e8a5db026963f5bfeac842d9d3f2cc8cde323b49", + "version" : "1.0.0" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms.git", + "state" : { + "revision" : "87e50f483c54e6efd60e885f7f5aa946cee68023", + "version" : "1.2.1" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "c5d11a805e765f52ba34ec7284bd4fcd6ba68615", + "version" : "1.7.0" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "b601256eab081c0f92f059e12818ac1d4f178ff7", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "7b847a3b7008b2dc2f47ca3110d8c782fb2e5c7e", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-nio", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-nio.git", + "state" : { + "revision" : "cd6710454f25733900e133c6caf5188952763c36", + "version" : "2.98.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0c0290ff6b24942dadb83a929ffaaa1481df04a2", + "version" : "1.1.1" + } + }, + { + "identity" : "swift-system", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-system.git", + "state" : { + "revision" : "395a77f0aa927f0ff73941d7ac35f2b46d47c9db", + "version" : "1.6.3" + } + }, + { + "identity" : "texttable", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ordo-one/TextTable.git", + "state" : { + "revision" : "a27a07300cf4ae322e0079ca0a475c5583dd575f", + "version" : "0.0.2" + } + } + ], + "version" : 2 +} diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift new file mode 100644 index 0000000..d99865b --- /dev/null +++ b/Benchmarks/Package.swift @@ -0,0 +1,27 @@ +// swift-tools-version:5.10 +import PackageDescription + +let package = Package( + name: "Benchmarks", + platforms: [.macOS(.v13)], + dependencies: [ + .package(name: "DataLoader", path: "../"), + .package(url: "https://github.com/ordo-one/package-benchmark", from: "1.4.0"), + .package(url: "https://github.com/apple/swift-nio.git", from: "2.84.0"), + ], + targets: [ + .executableTarget( + name: "Benchmarks", + dependencies: [ + .product(name: "Benchmark", package: "package-benchmark"), + .product(name: "AsyncDataLoader", package: "DataLoader"), + .product(name: "DataLoader", package: "DataLoader"), + .product(name: "NIO", package: "swift-nio"), + ], + path: "Benchmarks", + plugins: [ + .plugin(name: "BenchmarkPlugin", package: "package-benchmark") + ] + ) + ] +)