是否有一种方法可以确定一个方法需要执行多少时间(以毫秒为单位)?


当前回答

mach_absolute_time()有一个方便的包装器——它是来自CoreAnimation框架的CACurrentMediaTime()函数。

与NSDate或CFAbsoluteTimeGetCurrent()偏移量不同, mach_absolute_time()和CACurrentMediaTime()基于 主机内部时钟,精确,单原子测量,且不受影响 外部时间参考的更改,例如由时间引起的更改 区域、夏令时或闰秒。


ObjC

#import <QuartzCore/QuartzCore.h>

CFTimeInterval startTime = CACurrentMediaTime();
// Do your stuff here
CFTimeInterval endTime = CACurrentMediaTime();
NSLog(@"Total Runtime: %g s", endTime - startTime);

斯威夫特

import QuartzCore

let startTime = CACurrentMediaTime()
// Do your stuff here
let endTime = CACurrentMediaTime()
print("Total Runtime: \(endTime - startTime) s")

其他回答

在Swift中,我使用:

在我的Macros.swift中,我刚刚添加了

var startTime = NSDate()
func TICK(){ startTime =  NSDate() }
func TOCK(function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__){
    println("\(function) Time: \(startTime.timeIntervalSinceNow)\nLine:\(line) File: \(file)")
}

你现在可以在任何地方打电话

TICK()

// your code to be tracked

TOCK()

斯威夫特5.0

   var startTime = NSDate()
func TICK(){ startTime =  NSDate() }
func TOCK(function: String = #function, file: String = #file, line: Int = #line){
    print("\(function) Time: \(startTime.timeIntervalSinceNow)\nLine:\(line) File: \(file)")
}

这段代码是基于Ron的代码翻译成Swift的,他有功劳 我在全球范围内使用开始日期,任何改进建议都是欢迎的

这里有一个Swift 3的解决方案,可以在任何地方对代码进行等分,以找到长时间运行的进程。

var increment: Int = 0

var incrementTime = NSDate()

struct Instrumentation {
    var title: String
    var point: Int
    var elapsedTime: Double

    init(_ title: String, _ point: Int, _ elapsedTime: Double) {
        self.title = title
        self.point = point
        self.elapsedTime = elapsedTime
    }
}

var elapsedTimes = [Instrumentation]()

func instrument(_ title: String) {
    increment += 1
    let incrementedTime = -incrementTime.timeIntervalSinceNow
    let newPoint = Instrumentation(title, increment, incrementedTime)
    elapsedTimes.append(newPoint)
    incrementTime = NSDate()
}

用法:-

instrument("View Did Appear")

print("ELAPSED TIMES \(elapsedTimes)")

样例输出:

[MyApp.SomeViewController.]仪器仪表(标题:“开始视图 Did Load", point: 1, elapsedTime: 0.040504038333892822), MyApp.SomeViewController。检测(标题:“完成添加 SubViews", point: 2, elapsedTime: 0.010585010051727295), MyApp.SomeViewController。仪器仪表(标题:“视图已出现”, 点:3,elapsedTime: 0.56564098596572876)]

我在我的utils库中使用这个(Swift 4.2):

public class PrintTimer {
    let start = Date()
    let name: String

    public init(file: String=#file, line: Int=#line, function: String=#function, name: String?=nil) {
        let file = file.split(separator: "/").last!
        self.name = name ?? "\(file):\(line) - \(function)"
    }

    public func done() {
        let end = Date()
        print("\(self.name) took \((end.timeIntervalSinceReferenceDate - self.start.timeIntervalSinceReferenceDate).roundToSigFigs(5)) s.")
    }
}

…然后调用如下方法:

func myFunctionCall() {
    let timer = PrintTimer()
    // ...
    timer.done()
}

…运行后在控制台中看起来是这样的:

MyFile.swift:225 - myFunctionCall() took 1.8623 s.

虽然不像上面的TICK/TOCK那样简洁,但它足以清楚地看到它在做什么,并自动包括正在计时的内容(通过文件、方法开头的行和函数名)。显然,如果我想要更多的细节(例如,如果我不只是计时一个方法调用,因为是通常的情况下,而是在该方法内计时块),我可以在PrintTimer init上添加“name="Foo""参数来命名它除了默认值之外的东西。

NSDate *methodStart = [NSDate date];

/* ... Do whatever you need to do ... */

NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);

迅速:

let methodStart = NSDate()

/* ... Do whatever you need to do ... */

let methodFinish = NSDate()
let executionTime = methodFinish.timeIntervalSinceDate(methodStart)
print("Execution time: \(executionTime)")

Swift3:

let methodStart = Date()

/* ... Do whatever you need to do ... */

let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(methodStart)
print("Execution time: \(executionTime)")

易于使用,具有亚毫秒精度。

既然你想优化时间从一个页面移动到另一个UIWebView,这是不是意味着你真的在寻找优化Javascript加载这些页面?

为此,我想看看WebKit分析器,就像这里所说的:

http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/

另一种方法是从高层次开始,思考如何设计有问题的网页,使用AJAX样式的页面加载来最小化加载时间,而不是每次都刷新整个web视图。