diff --git a/Benchmarks/Benchmarks/DataIO/BenchmarkDataIO.swift b/Benchmarks/Benchmarks/DataIO/BenchmarkDataIO.swift index b2fb88a20..454333fcd 100644 --- a/Benchmarks/Benchmarks/DataIO/BenchmarkDataIO.swift +++ b/Benchmarks/Benchmarks/DataIO/BenchmarkDataIO.swift @@ -16,7 +16,8 @@ import func Benchmark.blackHole #if FOUNDATION_FRAMEWORK import Foundation #else -@testable import FoundationEssentials +import FoundationEssentials +import FoundationBenchmarkSupport #endif @@ -27,16 +28,10 @@ import Glibc import Darwin #endif -#if !FOUNDATION_FRAMEWORK -func testPath() -> String { - // Generate a random file name - FileManager.default.temporaryDirectory.path.appendingPathComponent("testfile-\(UUID().uuidString)") -} -#else func testPath() -> URL { + // Generate a random file name FileManager.default.temporaryDirectory.appending(path: "testfile-\(UUID().uuidString)", directoryHint: .notDirectory) } -#endif func generateTestData(count: Int) -> Data { let memory = malloc(count)! @@ -51,17 +46,10 @@ func generateTestData(count: Int) -> Data { return Data(bytesNoCopy: ptr, count: count, deallocator: .free) } -#if !FOUNDATION_FRAMEWORK -func cleanup(at path: String) { - try? FileManager.default.removeItem(atPath: path) - // Ignore any errors -} -#else func cleanup(at path: URL) { try? FileManager.default.removeItem(at: path) // Ignore any errors } -#endif // 16 MB file, big enough to trigger things like chunking let data = generateTestData(count: 1 << 24) diff --git a/Benchmarks/Benchmarks/String/BenchmarkString.swift b/Benchmarks/Benchmarks/String/BenchmarkString.swift index 49578f0db..12d4981c2 100644 --- a/Benchmarks/Benchmarks/String/BenchmarkString.swift +++ b/Benchmarks/Benchmarks/String/BenchmarkString.swift @@ -17,6 +17,13 @@ import func Benchmark.blackHole import Foundation #else import FoundationEssentials +import FoundationBenchmarkSupport +#endif + +#if FOUNDATION_FRAMEWORK +private typealias Encoding = String.Encoding +#else +private typealias Encoding = FoundationEssentialsStringEncoding #endif let benchmarks = { @@ -85,21 +92,21 @@ let benchmarks = { Benchmark("utf16-decode", configuration: .init(warmupIterations: 1, scalingFactor: .kilo)) { benchmark in for _ in benchmark.scaledIterations { autoreleasepool { - blackHole(String(bytes: asciiSmallStrDataUTF16BE, encoding: .utf16BigEndian)) - blackHole(String(bytes: nonAsciiSmallStrDataUTF16BE, encoding: .utf16BigEndian)) + blackHole(String(bytes: asciiSmallStrDataUTF16BE, encoding: Encoding.utf16BigEndian)) + blackHole(String(bytes: nonAsciiSmallStrDataUTF16BE, encoding: Encoding.utf16BigEndian)) - blackHole(String(bytes: asciiLargeStrDataUTF16BE, encoding: .utf16BigEndian)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF16BE, encoding: .utf16BigEndian)) + blackHole(String(bytes: asciiLargeStrDataUTF16BE, encoding: Encoding.utf16BigEndian)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF16BE, encoding: Encoding.utf16BigEndian)) - blackHole(String(bytes: asciiSmallStrDataUTF16LE, encoding: .utf16LittleEndian)) - blackHole(String(bytes: nonAsciiSmallStrDataUTF16LE, encoding: .utf16LittleEndian)) + blackHole(String(bytes: asciiSmallStrDataUTF16LE, encoding: Encoding.utf16LittleEndian)) + blackHole(String(bytes: nonAsciiSmallStrDataUTF16LE, encoding: Encoding.utf16LittleEndian)) - blackHole(String(bytes: asciiLargeStrDataUTF16LE, encoding: .utf16LittleEndian)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF16LE, encoding: .utf16LittleEndian)) + blackHole(String(bytes: asciiLargeStrDataUTF16LE, encoding: Encoding.utf16LittleEndian)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF16LE, encoding: Encoding.utf16LittleEndian)) // Use big endian input data with plain utf16 to get a valid string. - blackHole(String(bytes: asciiLargeStrDataUTF16BE, encoding: .utf16)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF16BE, encoding: .utf16)) + blackHole(String(bytes: asciiLargeStrDataUTF16BE, encoding: Encoding.utf16)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF16BE, encoding: Encoding.utf16)) } } } @@ -130,21 +137,21 @@ let benchmarks = { Benchmark("utf32-decode", configuration: .init(warmupIterations: 1, scalingFactor: .kilo)) { benchmark in for _ in benchmark.scaledIterations { autoreleasepool { - blackHole(String(bytes: asciiSmallStrDataUTF32BE, encoding: .utf32BigEndian)) - blackHole(String(bytes: nonAsciiSmallStrDataUTF32BE, encoding: .utf32BigEndian)) + blackHole(String(bytes: asciiSmallStrDataUTF32BE, encoding: Encoding.utf32BigEndian)) + blackHole(String(bytes: nonAsciiSmallStrDataUTF32BE, encoding: Encoding.utf32BigEndian)) - blackHole(String(bytes: asciiLargeStrDataUTF32BE, encoding: .utf32BigEndian)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF32BE, encoding: .utf32BigEndian)) + blackHole(String(bytes: asciiLargeStrDataUTF32BE, encoding: Encoding.utf32BigEndian)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF32BE, encoding: Encoding.utf32BigEndian)) - blackHole(String(bytes: asciiSmallStrDataUTF32LE, encoding: .utf32LittleEndian)) - blackHole(String(bytes: nonAsciiSmallStrDataUTF32LE, encoding: .utf32LittleEndian)) + blackHole(String(bytes: asciiSmallStrDataUTF32LE, encoding: Encoding.utf32LittleEndian)) + blackHole(String(bytes: nonAsciiSmallStrDataUTF32LE, encoding: Encoding.utf32LittleEndian)) - blackHole(String(bytes: asciiLargeStrDataUTF32LE, encoding: .utf32LittleEndian)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF32LE, encoding: .utf32LittleEndian)) + blackHole(String(bytes: asciiLargeStrDataUTF32LE, encoding: Encoding.utf32LittleEndian)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF32LE, encoding: Encoding.utf32LittleEndian)) // Use big endian input data with plain UTF32 to get a valid string. - blackHole(String(bytes: asciiLargeStrDataUTF32BE, encoding: .utf32)) - blackHole(String(bytes: nonAsciiLargeStrDataUTF32BE, encoding: .utf32)) + blackHole(String(bytes: asciiLargeStrDataUTF32BE, encoding: Encoding.utf32)) + blackHole(String(bytes: nonAsciiLargeStrDataUTF32BE, encoding: Encoding.utf32)) } } } @@ -153,7 +160,7 @@ let benchmarks = { let str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." Benchmark("read-utf8", configuration: .init(warmupIterations: 1, scalingFactor: .kilo)) { benchmark in - let rootURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(UUID().uuidString, isDirectory: true) + let rootURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) let fileURL = rootURL.appending(path: "benchmark.txt", directoryHint: .notDirectory) try! FileManager.default.createDirectory(at: rootURL, withIntermediateDirectories: true) defer { @@ -170,7 +177,7 @@ let benchmarks = { } Benchmark("read-utf16", configuration: .init(warmupIterations: 1, scalingFactor: .kilo)) { benchmark in - let rootURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true).appendingPathComponent(UUID().uuidString, isDirectory: true) + let rootURL = FileManager.default.temporaryDirectory.appendingPathComponent(UUID().uuidString, isDirectory: true) let fileURL = rootURL.appending(path: "benchmark.txt", directoryHint: .notDirectory) try! FileManager.default.createDirectory(at: rootURL, withIntermediateDirectories: true) defer { diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift index 6463366ec..53820267c 100644 --- a/Benchmarks/Package.swift +++ b/Benchmarks/Package.swift @@ -10,6 +10,13 @@ let package = Package( .package(url: "https://github.com/ordo-one/package-benchmark.git", from: "1.11.1"), ], targets: [ + .target( + name: "FoundationBenchmarkSupport", + dependencies: [ + .product(name: "FoundationEssentials", package: "swift-foundation-local"), + ] + ), + .executableTarget( name: "PredicateBenchmarks", dependencies: [ @@ -49,6 +56,7 @@ let package = Package( dependencies: [ .product(name: "FoundationEssentials", package: "swift-foundation-local"), .product(name: "Benchmark", package: "package-benchmark"), + "FoundationBenchmarkSupport", ], path: "Benchmarks/DataIO", plugins: [ @@ -72,6 +80,7 @@ let package = Package( dependencies: [ .product(name: "FoundationEssentials", package: "swift-foundation-local"), .product(name: "Benchmark", package: "package-benchmark"), + "FoundationBenchmarkSupport", ], path: "Benchmarks/String", plugins: [ diff --git a/Benchmarks/Sources/FoundationBenchmarkSupport/FoundationBenchmarkSupport.swift b/Benchmarks/Sources/FoundationBenchmarkSupport/FoundationBenchmarkSupport.swift new file mode 100644 index 000000000..4a0163807 --- /dev/null +++ b/Benchmarks/Sources/FoundationBenchmarkSupport/FoundationBenchmarkSupport.swift @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2024 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import FoundationEssentials + +package func autoreleasepool(_ block: () -> T) -> T { block() } + +package typealias FoundationEssentialsStringEncoding = String.Encoding