Swift TimeProfiler
April 02, 2025 at 8:28AMOnce the main item was create I needed to refine it a little so It both returns the elapsed time and also works with async functions. The result is pretty sweet.
import Foundation
/// A utility struct for measuring the execution time of synchronous and asynchronous code blocks.
struct TimeProfiler {
/// Measure the execution time of a synchronous block.
///
/// - Example:
///```swift
/// let (result, time) = TimeProfiler.measure("ButtonTapped.Accept") {
/// dispatch(DialogView.DismissDialog(dialog: activationDialog))
/// }
///```
static func measureAsyncWithTime<T>(_ label: String? = nil, block: () -> T) -> (result: T, milliseconds: Double) {
let startTime = CFAbsoluteTimeGetCurrent()
let result = block()
let endTime = CFAbsoluteTimeGetCurrent()
let elapsed = (endTime - startTime) * 1000
printTime(label, elapsed)
return (result, elapsed)
}
/// Measure the execution time of an asynchronous block.
///
/// - Example:
///```swift
/// let (result, time) = try await TimeProfiler.measure("ButtonTapped.Accept") {
/// return try await env.service.acceptRequestAsync(activationId: activation.id, activationRequestId: requestId)
/// }
///```
static func measureAsyncWithTime<T>(_ label: String? = nil, block: () async throws -> T) async rethrows -> (result: T, milliseconds: Double) {
let startTime = CFAbsoluteTimeGetCurrent()
let result = try await block()
let endTime = CFAbsoluteTimeGetCurrent()
let elapsed = (endTime - startTime) * 1000
printTime(label, elapsed)
return (result, elapsed)
}
/// Measure the execution time of a synchronous block.
///
/// - Example:
///```swift
/// TimeProfiler.measure("ButtonTapped.Accept") {
/// dispatch(DialogView.DismissDialog(dialog: activationDialog))
/// }
///```
static func measure<T>(_ label: String? = nil, block: () -> T) -> (T) {
let startTime = CFAbsoluteTimeGetCurrent()
let result = block()
let endTime = CFAbsoluteTimeGetCurrent()
let elapsed = (endTime - startTime) * 1000
printTime(label, elapsed)
return (result)
}
/// Measure the execution time of an asynchronous block.
///
/// - Example:
///```swift
/// let result = try await TimeProfiler.measure("ButtonTapped.Accept") {
/// return try await env.service.acceptRequestAsync(activationId: activation.id, activationRequestId: requestId)
/// }
///```
static func measureAsync<T>(_ label: String? = nil, block: () async throws -> T) async rethrows -> (T) {
let startTime = CFAbsoluteTimeGetCurrent()
let result = try await block()
let endTime = CFAbsoluteTimeGetCurrent()
let elapsed = (endTime - startTime) * 1000
printTime(label, elapsed)
return (result)
}
/// Internal TimeProfiler func to print time and label info to console.
static private func printTime(_ label: String? = nil, _ elapsed: Double) {
if let label = label {
debugPrint("⏱️ [\(label)] Execution time: \(elapsed) ms")
} else {
debugPrint("⏱️ Execution time = \(elapsed) ms")
}
}
}
Happy Coding ;-)