Vaq*_*ita 111 time nsdate elapsedtime swift
我们如何衡量在Swift中运行函数所用的时间?我试图像这样显示经过的时间:"Elasped time is .05 seconds".看到在Java中,我们可以使用System.nanoTime(),是否有任何等效的方法可用于Swift来实现这一目的?
请看一下示例程序:
func isPrime(var number:Int) ->Bool {
var i = 0;
for i=2; i<number; i++ {
if(number % i == 0 && i != 0) {
return false;
}
}
return true;
}
var number = 5915587277;
if(isPrime(number)) {
println("Prime number");
} else {
println("NOT a prime number");
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*myP 197
这是我用来测量Swift中Project Euler问题的Swift函数
从Swift 3开始,现在有一个版本的Grand Central Dispatch"swiftified".所以正确的答案可能是使用DispatchTime API.
我的功能看起来像:
// Swift 3
func evaluateProblem(problemNumber: Int, problemBlock: () -> Int) -> Answer
{
print("Evaluating problem \(problemNumber)")
let start = DispatchTime.now() // <<<<<<<<<< Start time
let myGuess = problemBlock()
let end = DispatchTime.now() // <<<<<<<<<< end time
let theAnswer = self.checkAnswer(answerNum: "\(problemNumber)", guess: myGuess)
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds // <<<<< Difference in nano seconds (UInt64)
let timeInterval = Double(nanoTime) / 1_000_000_000 // Technically could overflow for long running tests
print("Time to evaluate problem \(problemNumber): \(timeInterval) seconds")
return theAnswer
}
Run Code Online (Sandbox Code Playgroud)
对于Swift 1和2,我的函数使用NSDate:
// Swift 1
func evaluateProblem(problemNumber: Int, problemBlock: () -> Int) -> Answer
{
println("Evaluating problem \(problemNumber)")
let start = NSDate() // <<<<<<<<<< Start time
let myGuess = problemBlock()
let end = NSDate() // <<<<<<<<<< end time
let theAnswer = self.checkAnswer(answerNum: "\(problemNumber)", guess: myGuess)
let timeInterval: Double = end.timeIntervalSinceDate(start) // <<<<< Difference in seconds (double)
println("Time to evaluate problem \(problemNumber): \(timeInterval) seconds")
return theAnswer
}
Run Code Online (Sandbox Code Playgroud)
请注意,不建议使用NSdate作为定时功能:" 由于与外部时间参考同步或由于时钟的明确用户更改,系统时间可能会减少. "
Kla*_*aas 66
这是一个基于CoreFoundations 的方便的计时器类CFAbsoluteTime:
import CoreFoundation
class ParkBenchTimer {
let startTime:CFAbsoluteTime
var endTime:CFAbsoluteTime?
init() {
startTime = CFAbsoluteTimeGetCurrent()
}
func stop() -> CFAbsoluteTime {
endTime = CFAbsoluteTimeGetCurrent()
return duration!
}
var duration:CFAbsoluteTime? {
if let endTime = endTime {
return endTime - startTime
} else {
return nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
let timer = ParkBenchTimer()
// ... a long runnig task ...
println("The task took \(timer.stop()) seconds.")
Run Code Online (Sandbox Code Playgroud)
Fra*_* Yu 45
clock,, ProcessInfo.systemUptime或DispatchTime用于简单的启动时间.据我所知,至少有十种方法可以衡量经过的时间:
ProcessInfo.systemUptime.mach_absolute_time与此答案中mach_timebase_info提到的一样.clock()在POSIX标准.times()在POSIX标准.(太复杂了,因为我们需要考虑用户时间与系统时间,并涉及子进程.)DispatchTime (JeremyP在接受的答案中提到的围绕Mach时间API的包装器).CACurrentMediaTime().(永远不要将它们用于指标:见下面原因)
NSDate/ Date正如其他人所说.CFAbsoluteTime 如别人所说.DispatchWallTime.gettimeofday()在POSIX标准.备选方案1,2和3详述如下.
do {
let info = ProcessInfo.processInfo
let begin = info.systemUptime
// do something
let diff = (info.systemUptime - begin)
}
Run Code Online (Sandbox Code Playgroud)
diff:NSTimeInterval以秒为单位的经过时间在哪里.
do {
var info = mach_timebase_info(numer: 0, denom: 0)
mach_timebase_info(&info)
let begin = mach_absolute_time()
// do something
let diff = Double(mach_absolute_time() - begin) * Double(info.numer) / Double(info.denom)
}
Run Code Online (Sandbox Code Playgroud)
diff:Double经过的时间在哪里纳秒.
do {
let begin = clock()
// do something
let diff = Double(clock() - begin) / Double(CLOCKS_PER_SEC)
}
Run Code Online (Sandbox Code Playgroud)
diff:Double以秒为单位的经过时间在哪里.
重复调用此函数并不能保证单调增加结果.
原因类似于Java中的currentTimeMillisvsnanoTime:
你不能将它用于其他目的.原因是没有计算机的时钟是完美的; 它总是漂移,偶尔需要纠正.这种修正可能是手动发生的,或者在大多数机器的情况下,有一个运行的过程并不断对系统时钟("挂钟")进行小的修正.这些往往经常发生.只要有闰秒,就会发生另一次这样的修正.
这里CFAbsoluteTime提供挂钟时间而不是启动时间.NSDate也是挂钟时间.
Mau*_*ino 29
斯威夫特4最短答案:
let startingPoint = Date()
// ... intensive task
print("\(startingPoint.timeIntervalSinceNow * -1) seconds elapsed")
Run Code Online (Sandbox Code Playgroud)
它会打印出类似于1.02107906341553秒的时间(当然时间会因任务而异,我只是向你们展示这个测量的小数精度等级).
希望它从现在开始帮助Swift 4中的某个人!
小智 14
只需复制和粘贴此功能。用 swift 5 编写。在此处复制 JeremyP。
func calculateTime(block : (() -> Void)) {
let start = DispatchTime.now()
block()
let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
let timeInterval = Double(nanoTime) / 1_000_000_000
print("Time: \(timeInterval) seconds")
}
Run Code Online (Sandbox Code Playgroud)
使用它就像
calculateTime {
exampleFunc()// function whose execution time to be calculated
}
Run Code Online (Sandbox Code Playgroud)
小智 13
let start = NSDate()
for index in 1...10000 {
// do nothing
}
let elapsed = start.timeIntervalSinceNow
// elapsed is a negative value.
Run Code Online (Sandbox Code Playgroud)
看起来iOS 13引入了一个新的 API 来使用DispatchTime,无需手动计算两个时间戳之间的差异。
let start: DispatchTime = .now()
heavyTaskToMeasure()
let duration = start.distance(to: .now())
print(duration)
// prints: nanoseconds(NUMBER_OF_NANOSECONDS_BETWEEN_TWO_TIMESTAMPS)
Run Code Online (Sandbox Code Playgroud)
遗憾的是没有提供文档,但经过一些测试后,看起来案例.nanoseconds总是被返回。
通过简单的扩展,您可以将其转换DispatchTimeInterval为TimeInterval. 信用
extension TimeInterval {
init?(dispatchTimeInterval: DispatchTimeInterval) {
switch dispatchTimeInterval {
case .seconds(let value):
self = Double(value)
case .milliseconds(let value):
self = Double(value) / 1_000
case .microseconds(let value):
self = Double(value) / 1_000_000
case .nanoseconds(let value):
self = Double(value) / 1_000_000_000
case .never:
return nil
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以创建一个time测量呼叫的功能.我被Klaas的答案所鼓舞.
func time <A> (f: @autoclosure () -> A) -> (result:A, duration: String) {
let startTime = CFAbsoluteTimeGetCurrent()
let result = f()
let endTime = CFAbsoluteTimeGetCurrent()
return (result, "Elapsed time is \(endTime - startTime) seconds.")
}
Run Code Online (Sandbox Code Playgroud)
此函数允许您像这样调用它time (isPrime(7)),它将返回包含结果的元组和经过时间的字符串描述.
如果您只希望经过的时间,您可以这样做 time (isPrime(7)).duration
| 归档时间: |
|
| 查看次数: |
71863 次 |
| 最近记录: |