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


当前回答

对于OS X上的细粒度计时,您应该使用在<mach/mach_time.h>中声明的mach_absolute_time():

#include <mach/mach_time.h>
#include <stdint.h>

// Do some stuff to setup for timing
const uint64_t startTime = mach_absolute_time();
// Do some stuff that you want to time
const uint64_t endTime = mach_absolute_time();

// Time elapsed in Mach time units.
const uint64_t elapsedMTU = endTime - startTime;

// Get information for converting from MTU to nanoseconds
mach_timebase_info_data_t info;
if (mach_timebase_info(&info))
   handleErrorConditionIfYoureBeingCareful();

// Get elapsed time in nanoseconds:
const double elapsedNS = (double)elapsedMTU * (double)info.numer / (double)info.denom;

当然,关于细粒度度量的通常警告也适用;您可能最好多次调用测试中的例程,并求平均值/取最小值/一些其他形式的处理。

此外,请注意,您可能会发现使用Shark等工具对应用程序运行进行概要分析更有用。这不会为您提供确切的时间信息,但它会告诉您应用程序的时间在哪里花费了多少百分比,这通常更有用(但并不总是如此)。

其他回答

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

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

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

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

这里有另一种方法,在Swift中,使用defer关键字来做到这一点

func methodName() {
  let methodStart = Date()
  defer {
    let executionTime = Date().timeIntervalSince(methodStart)
    print("Execution time: \(executionTime)")
  }
  // do your stuff here
}

来自苹果的文档:defer语句用于在将程序控制权转移到该defer语句出现的范围之外之前执行代码。

这类似于try/finally块,优点是将相关代码分组。

我在我的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""参数来命名它除了默认值之外的东西。

我使用这个代码:

#import <mach/mach_time.h>

float TIME_BLOCK(NSString *key, void (^block)(void)) {
    mach_timebase_info_data_t info;
    if (mach_timebase_info(&info) != KERN_SUCCESS)
    {
        return -1.0;
    }

    uint64_t start = mach_absolute_time();
    block();
    uint64_t end = mach_absolute_time();
    uint64_t elapsed = end - start;

    uint64_t nanos = elapsed * info.numer / info.denom;
    float cost = (float)nanos / NSEC_PER_SEC;

    NSLog(@"key: %@ (%f ms)\n", key, cost * 1000);
    return cost;
}

许多答案很奇怪,并没有真正以毫秒为单位给出结果(而是以秒或其他单位):

这里是我用来获得MS(毫秒):

迅速:

let startTime = NSDate().timeIntervalSince1970 * 1000

// your Swift code

let endTimeMinusStartTime = NSDate().timeIntervalSince1970 * 1000 - startTime
print("time code execution \(endTimeMinStartTime) ms")

objective - c:

double startTime = [[NSDate date] timeIntervalSince1970] * 1000.0;

// your Objective-C code

double endTimeMinusStartTime = [[NSDate date] timeIntervalSince1970] * 1000.0 - startTime;
printf("time code execution %f ms\n", endTimeMinusStartTime );