Swift 코드 실행을 벤치마킹하는 방법은 무엇입니까?
다음 외에 Swift로 작성된 코드 블록을 실행하는 데 필요한 정확한 시간을 제공하는 방법 / 소프트웨어가 있습니까?
let date_start = NSDate()
// Code to be executed
println("\(-date_start.timeIntervalSinceNow)")
코드 블록에 대한 독립형 타이밍 함수를 원하면 다음 Swift 도우미 함수를 사용합니다.
func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for \(title): \(timeElapsed) s.")
}
func timeElapsedInSecondsWhenRunningCode(operation: ()->()) -> Double {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
return Double(timeElapsed)
}
전자는 주어진 코드 섹션에 필요한 시간을 로그 아웃하고 후자는이를 float로 반환합니다. 첫 번째 변형의 예 :
printTimeElapsedWhenRunningCode(title:"map()") {
let resultArray1 = randoms.map { pow(sin(CGFloat($0)), 10.0) }
}
다음과 같이 로그 아웃됩니다.
map ()에 대한 경과 시간 : 0.0617449879646301 초
주의하십시오 스위프트 벤치 마크는 사용자가 선택한 최적화의 수준에 따라 크게 달라집니다 이는 신속한 실행 시간의 상대적 비교를 위해 유용 할 수 있도록. 심지어 베타 버전별로 변경 될 수 있습니다.
특정 코드 블록의 성능에 대한 통찰력을 얻고 편집 할 때 성능이 저하되지 않는지 확인하려면 .NET 과 같은 XCTest의 성능 측정 기능을 사용하는 것이 가장 좋습니다 measure(_ block: () -> Void)
.
벤치마킹하려는 방법을 실행하는 단위 테스트를 작성하면 해당 단위 테스트가 여러 번 실행되어 필요한 시간과 결과 편차를 제공합니다.
func testExample() {
self.measure {
//do something you want to measure
}
}
Apple 문서에서 Xcode로 테스트-> 성능 테스트 에서 자세한 정보를 찾을 수 있습니다.
이 함수를 사용하여 비동기 및 동기 코드를 측정 할 수 있습니다.
import Foundation
func measure(_ title: String, block: (@escaping () -> ()) -> ()) {
let startTime = CFAbsoluteTimeGetCurrent()
block {
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("\(title):: Time: \(timeElapsed)")
}
}
따라서 기본적으로 함수를 매개 변수로 받아들이는 블록을 전달하여 측정을 완료 할 때를 알리는 데 사용합니다.
예를 들어 "myAsyncCall"이라는 호출에 걸리는 시간을 측정하려면 다음과 같이 호출합니다.
measure("some title") { finish in
myAsyncCall {
finish()
}
// ...
}
동기 코드의 경우 :
measure("some title") { finish in
// code to benchmark
finish()
// ...
}
XCTest의 measureBlock과 비슷해야하지만 정확히 어떻게 구현되는지 모르겠습니다.
벤치마킹 기능-Swift 4.2
이것은 테스트 라벨링, 많은 테스트 수행 및 실행 시간 평균화, 테스트간에 호출 할 설정 블록 (예 : 정렬 알고리즘 측정 사이에 배열 섞기), 벤치마킹의 명확한 인쇄를 허용하는 믿을 수 없을 정도로 다재다능한 벤치마킹 기능입니다. 결과 및 평균 실행 시간도 Double
.
다음을 시도하십시오.
@_transparent @discardableResult public func measure(label: String? = nil, tests: Int = 1, printResults output: Bool = true, setup: @escaping () -> Void = { return }, _ block: @escaping () -> Void) -> Double {
guard tests > 0 else { fatalError("Number of tests must be greater than 0") }
var avgExecutionTime : CFAbsoluteTime = 0
for _ in 1...tests {
setup()
let start = CFAbsoluteTimeGetCurrent()
block()
let end = CFAbsoluteTimeGetCurrent()
avgExecutionTime += end - start
}
avgExecutionTime /= CFAbsoluteTime(tests)
if output {
let avgTimeStr = "\(avgExecutionTime)".replacingOccurrences(of: "e|E", with: " × 10^", options: .regularExpression, range: nil)
if let label = label {
print(label, "▿")
print("\tExecution time: \(avgTimeStr)s")
print("\tNumber of tests: \(tests)\n")
} else {
print("Execution time: \(avgTimeStr)s")
print("Number of tests: \(tests)\n")
}
}
return avgExecutionTime
}
용법
var arr = Array(1...1000).shuffled()
measure(label: "Map to String") {
let _ = arr.map { String($0) }
}
measure(label: "Apple Shuffle", tests: 1000, setup: { arr.shuffle() }) {
arr.sort()
}
measure {
let _ = Int.random(in: 1...10000)
}
let mathExecutionTime = measure(printResults: false) {
let _ = 219 * 354
}
print("Math Execution Time: \(mathExecutionTime * 1000)ms")
// Prints:
//
// Map to String ▿
// Execution time: 0.021643996238708496s
// Number of tests: 1
//
// Apple's Sorting Method ▿
// Execution time: 0.0010601345300674438s
// Number of tests: 1000
//
// Execution time: 6.198883056640625 × 10^-05s
// Number of tests: 1
//
// Math Execution Time: 0.016927719116210938ms
//
참고 : measure
실행 시간도 반환합니다. label
, tests
및 setup
인수는 선택 사항입니다. printResults
인수로 설정됩니다 true
기본적으로.
I like Brad Larson's answer for a simple test that you can even run in a Playground. For my own needs I've tweaked it a bit:
- I've wrapped the call to the function I want to test in a testing function, which gives me space to play around with different arguments if I want to.
- The testing function returns its name, so I don't have to include the 'title' parameter in the
averageTimeTo()
benchmarking function. - The benchmarking function allows you to optionally specify how many repetitions to perform (with a default of 10). It then reports both the total and average times.
- The benchmarking function prints to the console AND returns the
averageTime
(which you might expect from a function called 'averageTimeTo'), so there's no need for two separate functions that have almost identical functionality.
For example:
func myFunction(args: Int...) {
// Do something
}
func testMyFunction() -> String {
// Wrap the call to myFunction here, and optionally test with different arguments
myFunction(args: 1, 2, 3)
return #function
}
// Measure average time to complete test
func averageTimeTo(_ testFunction: () -> String, repeated reps: UInt = 10) -> Double {
let functionName = testFunction()
var totalTime = 0.0
for _ in 0..<reps {
let startTime = CFAbsoluteTimeGetCurrent()
testFunction()
let elapsedTime = CFAbsoluteTimeGetCurrent() - startTime
totalTime += elapsedTime
}
let averageTime = totalTime / Double(reps)
print("Total time to \(functionName) \(reps) times: \(totalTime) seconds")
print("Average time to \(functionName): \(averageTime) seconds\n")
return averageTime
}
averageTimeTo(testMyFunction)
// Total time to testMyFunction() 10 times: 0.000253915786743164 seconds
// Average time to testMyFunction(): 2.53915786743164e-05 seconds
averageTimeTo(testMyFunction, repeated: 1000)
// Total time to testMyFunction() 1000 times: 0.027538537979126 seconds
// Average time to testMyFunction(): 2.7538537979126e-05 seconds
참고URL : https://stackoverflow.com/questions/25006235/how-to-benchmark-swift-code-execution
'Development Tip' 카테고리의 다른 글
중첩 된 개체의 동적 설정 속성 (0) | 2020.12.06 |
---|---|
Google 결과에서 데이터를 긁어도 괜찮습니까? (0) | 2020.12.06 |
클릭시 Vue.js 토글 클래스 (0) | 2020.12.06 |
ngModel을 사용하여 부모 formGroup 지시문으로 양식 컨트롤을 등록 할 수 없습니다. (0) | 2020.12.06 |
Kotlin 코 루틴이 RxKotlin보다 얼마나 나은가요? (0) | 2020.12.06 |