// // PerformanceTestCase.swift // iOS Foundations // // Performance testing utilities // import XCTest /// Base class for performance tests /// /// Provides utilities for measuring and asserting performance characteristics. /// /// ## Example /// /// ```swift /// final class ImageProcessingPerformanceTests: PerformanceTestCase { /// /// func testImageLoadingPerformance() { /// measure { /// loadAndProcessImage() /// } /// } /// /// func testMemoryEfficiency() { /// measureMemory { /// loadLargeDataset() /// } /// assertMemoryUsage(lessThan: 50.0) // < 50 MB /// } /// } /// ``` /// open class PerformanceTestCase: XCTestCase { // MARK: - Thresholds /// Maximum acceptable memory usage in MB public var maxMemoryUsageMB: Double = 100.0 /// Maximum acceptable execution time in seconds public var maxExecutionTime: TimeInterval = 1.0 // MARK: - Memory Measurement /// Measure memory usage of a code block /// /// - Parameter block: The code block to measure /// - Returns: Memory used in bytes /// @discardableResult public func measureMemory(block: () -> Void) -> UInt64 { let before = currentMemoryUsage() block() let after = currentMemoryUsage() return after > before ? after - before : 0 } /// Assert memory usage is below threshold /// /// - Parameter maxMB: Maximum acceptable memory in MB /// public func assertMemoryUsage(lessThan maxMB: Double, file: StaticString = #file, line: UInt = #line) { let usageMB = Double(currentMemoryUsage()) / 1024.0 / 1024.0 XCTAssertLessThan( usageMB, maxMB, "Memory usage (\(String(format: "%.2f", usageMB)) MB) exceeds threshold (\(maxMB) MB)", file: file, line: line ) } // MARK: - Timing /// Measure execution time of a code block /// /// - Parameter block: The code block to measure /// - Returns: Execution time in seconds /// @discardableResult public func measureTime(block: () -> Void) -> TimeInterval { let start = Date() block() let end = Date() return end.timeIntervalSince(start) } /// Assert execution time is below threshold /// /// - Parameters: /// - maxTime: Maximum acceptable time in seconds /// - block: The code block to measure /// public func assertExecutionTime( lessThan maxTime: TimeInterval, block: () -> Void, file: StaticString = #file, line: UInt = #line ) { let time = measureTime(block: block) XCTAssertLessThan( time, maxTime, "Execution time (\(String(format: "%.3f", time))s) exceeds threshold (\(maxTime)s)", file: file, line: line ) } // MARK: - Private Helpers private func currentMemoryUsage() -> UInt64 { var taskInfo = mach_task_basic_info() var count = mach_msg_type_number_t(MemoryLayout.size) / 4 let kerr: kern_return_t = withUnsafeMutablePointer(to: &taskInfo) { $0.withMemoryRebound(to: integer_t.self, capacity: 1) { task_info( mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count ) } } return kerr == KERN_SUCCESS ? taskInfo.resident_size : 0 } }