mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			117 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Swift
		
	
		
		
			
		
	
	
			117 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Swift
		
	
| 
											8 years ago
										 | // | ||
| 
											7 years ago
										 | //  Copyright (c) 2019 Open Whisper Systems. All rights reserved. | ||
| 
											8 years ago
										 | // | ||
|  | 
 | ||
|  | import Foundation | ||
|  | 
 | ||
| 
											7 years ago
										 | /// Benchmark async code by calling the passed in block parameter when the work | ||
|  | /// is done. | ||
|  | /// | ||
|  | ///     BenchAsync(title: "my benchmark") { completeBenchmark in | ||
|  | ///         foo { | ||
| 
											7 years ago
										 | ///             // consider benchmarking of "foo" complete | ||
| 
											7 years ago
										 | ///             completeBenchmark() | ||
| 
											7 years ago
										 | /// | ||
|  | ///             // call any completion handler foo might have | ||
| 
											7 years ago
										 | ///             fooCompletion() | ||
|  | ///         } | ||
|  | ///     } | ||
|  | public func BenchAsync(title: String, block: (@escaping () -> Void) -> Void) { | ||
| 
											7 years ago
										 |     let startTime = CACurrentMediaTime() | ||
| 
											8 years ago
										 | 
 | ||
|  |     block { | ||
| 
											7 years ago
										 |         let timeElapsed = CACurrentMediaTime() - startTime | ||
| 
											7 years ago
										 |         let formattedTime = String(format: "%0.2fms", timeElapsed * 1000) | ||
|  |         Logger.debug("[Bench] title: \(title), duration: \(formattedTime)") | ||
| 
											8 years ago
										 |     } | ||
|  | } | ||
|  | 
 | ||
|  | public func Bench(title: String, block: () -> Void) { | ||
|  |     BenchAsync(title: title) { finish in | ||
|  |         block() | ||
|  |         finish() | ||
|  |     } | ||
|  | } | ||
| 
											7 years ago
										 | 
 | ||
| 
											7 years ago
										 | public func Bench(title: String, block: () throws -> Void) throws { | ||
|  |     var thrownError: Error? | ||
|  |     BenchAsync(title: title) { finish in | ||
|  |         do { | ||
|  |             try block() | ||
|  |         } catch { | ||
|  |             thrownError = error | ||
|  |         } | ||
|  |         finish() | ||
|  |     } | ||
|  |     if let errorToRethrow = thrownError { | ||
|  |         throw errorToRethrow | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
| 
											7 years ago
										 | /// When it's not convenient to retain the event completion handler, e.g. when the measured event | ||
|  | /// crosses multiple classes, you can use the BenchEvent tools | ||
|  | /// | ||
|  | ///     // in one class | ||
|  | ///     BenchEventStart(title: "message sending", eventId: message.id) | ||
| 
											7 years ago
										 | ///     beginTheWork() | ||
| 
											7 years ago
										 | /// | ||
| 
											7 years ago
										 | ///     ... | ||
| 
											7 years ago
										 | /// | ||
|  | ///    // in another class | ||
| 
											7 years ago
										 | ///    doTheLastThing() | ||
|  | ///    BenchEventComplete(eventId: message.id) | ||
| 
											7 years ago
										 | /// | ||
|  | /// Or in objc | ||
|  | /// | ||
|  | ///    [BenchManager startEventWithTitle:"message sending" eventId:message.id] | ||
|  | ///    ... | ||
| 
											7 years ago
										 | ///    [BenchManager completeEventWithEventId:eventId:message.id] | ||
| 
											7 years ago
										 | public func BenchEventStart(title: String, eventId: BenchmarkEventId) { | ||
|  |     BenchAsync(title: title) { finish in | ||
|  |         runningEvents[eventId] = Event(title: title, eventId: eventId, completion: finish) | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | public func BenchEventComplete(eventId: BenchmarkEventId) { | ||
|  |     guard let event = runningEvents.removeValue(forKey: eventId) else { | ||
|  |         Logger.debug("no active event with id: \(eventId)") | ||
|  |         return | ||
|  |     } | ||
|  | 
 | ||
|  |     event.completion() | ||
|  | } | ||
|  | 
 | ||
|  | public typealias BenchmarkEventId = String | ||
|  | 
 | ||
|  | private struct Event { | ||
|  |     let title: String | ||
|  |     let eventId: BenchmarkEventId | ||
|  |     let completion: () -> Void | ||
|  | } | ||
|  | 
 | ||
|  | private var runningEvents: [BenchmarkEventId: Event] = [:] | ||
|  | 
 | ||
|  | @objc | ||
|  | public class BenchManager: NSObject { | ||
|  | 
 | ||
|  |     @objc | ||
|  |     public class func startEvent(title: String, eventId: BenchmarkEventId) { | ||
|  |         BenchEventStart(title: title, eventId: eventId) | ||
|  |     } | ||
|  | 
 | ||
|  |     @objc | ||
|  |     public class func completeEvent(eventId: BenchmarkEventId) { | ||
|  |         BenchEventComplete(eventId: eventId) | ||
|  |     } | ||
|  | 
 | ||
|  |     @objc | ||
|  |     public class func benchAsync(title: String, block: (@escaping () -> Void) -> Void) { | ||
|  |         BenchAsync(title: title, block: block) | ||
|  |     } | ||
|  | 
 | ||
|  |     @objc | ||
|  |     public class func bench(title: String, block: () -> Void) { | ||
|  |         Bench(title: title, block: block) | ||
|  |     } | ||
|  | } |