如何以毫秒为单位记录方法的执行时间?

dan*_*dan 215 optimization time objective-c ios

有没有办法确定方法需要执行多长时间(以毫秒为单位)?

Mat*_*gan 425

NSDate *methodStart = [NSDate date];

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

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

迅速:

let methodStart = NSDate()

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

let methodFinish = NSDate()
let executionTime = methodFinish.timeIntervalSinceDate(methodStart)
print("Execution time: \(executionTime)")
Run Code Online (Sandbox Code Playgroud)

Swift3:

let methodStart = Date()

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

let methodFinish = Date()
let executionTime = methodFinish.timeIntervalSince(methodStart)
print("Execution time: \(executionTime)")
Run Code Online (Sandbox Code Playgroud)

易于使用,精度为亚毫秒级.

  • 我只是在大约30ms的水平上比较了`NSDate`和`mach_absolute_time()`.27对29,36对39,43对45.`NSDate`对我来说更容易使用,结果足够相似,不用担心`mach_absolute_time()`. (6认同)
  • 您可以使用%f - NSLog("executionTime =%f",executionTime)记录此值; (5认同)
  • 任何基于NSDate的东西都不能安全地测量通过时间,因为时间可以跳跃,甚至倒退.更安全的方法是使用mach_absolute_time,如此处的许多其他答案所示.这个应该被视为一个坏榜样.另请参阅相关答案,更详细地解释了这一点:http://stackoverflow.com/a/30363702/43615 (4认同)
  • @PeterWarbo NSTimeInterval是一个double的typedef,定义为秒 - 请参阅http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_DataTypes/Reference/reference.html (3认同)

Ron*_*Ron 249

这是我使用的两个单行宏:

#define TICK   NSDate *startTime = [NSDate date]
#define TOCK   NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

TICK;

/* ... Do Some Work Here ... */

TOCK;
Run Code Online (Sandbox Code Playgroud)

  • `#define TOCK NSLog(@"%s时间:%f",__ func __, - [startTime timeIntervalSinceNow])`这个答案也会返回定时器所用的功能.如果我用TICK TOCK来计时,我觉得这很有用多种功能. (30认同)
  • 哈哈.我喜欢! (13认同)
  • 是什么让这么好,就是滴答滴答是一个令人难忘的短语,记录几乎不需要考虑. (4认同)
  • 好主意@golmschenk!如果您想了解更多详细信息,还可以查看`__PRETTY_FUNCTION__`和`__LINE__`. (3认同)

Ste*_*non 48

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

#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;
Run Code Online (Sandbox Code Playgroud)

当然,关于细粒度测量的常见警告适用; 你可能最好多次调用被测例程,平均/采取最小/其他形式的处理.

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


Adr*_*oni 12

在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)")
}
Run Code Online (Sandbox Code Playgroud)

你现在可以随时随地打电话

TICK()

// your code to be tracked

TOCK()
Run Code Online (Sandbox Code Playgroud)
  • 这段代码基于Ron的代码转换为Swift,他有学分
  • 我在全球范围内使用开始日期,欢迎任何改进建议


小智 12

有一个方便的包装器mach_absolute_time()–它是一个CACurrentMediaTime()功能。

不像NSDateCFAbsoluteTimeGetCurrent()偏移, mach_absolute_time()CACurrentMediaTime()基于该内部主机时钟,精确的,单原子的措施,而不是在外部时间基准的变化,例如那些引起的时区,夏令时,或闰秒主题。


对象

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

迅速

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

  • 我认为这个答案值得更多的赞同。比使用`NSDate`更好。 (3认同)

bla*_*man 9

我知道这是一个旧的,但即使我发现自己再次徘徊,所以我想我会在这里提交自己的选择.

最好的办法是查看我的博客文章: Objective-C中的时间:秒表

基本上,我写了一个类,它以一种非常基本的方式停止观看,但是被封装,所以你只需要做以下事情:

[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];
Run Code Online (Sandbox Code Playgroud)

你最终得到:

MyApp[4090:15203]  -> Stopwatch: [My Timer] runtime: [0.029]
Run Code Online (Sandbox Code Playgroud)

在日志中......

再次,查看我的帖子多一点或下载它: MMStopwatch.zip


Ser*_*hin 7

我使用基于Ron的解决方案的宏.

#define TICK(XXX) NSDate *XXX = [NSDate date]
#define TOCK(XXX) NSLog(@"%s: %f", #XXX, -[XXX timeIntervalSinceNow])
Run Code Online (Sandbox Code Playgroud)

对于代码行:

TICK(TIME1);
/// do job here
TOCK(TIME1);
Run Code Online (Sandbox Code Playgroud)

我们将在控制台中看到类似:TIME1:0.096618

  • 你不能在一个上下文中使用@ Ron的解决方案两次.这是这个宏的主要原因. (2认同)

zub*_*bko 5

我使用非常少的单页类实现,其灵感来自这篇博文代码

#import <mach/mach_time.h>

@interface DBGStopwatch : NSObject

+ (void)start:(NSString *)name;
+ (void)stop:(NSString *)name;

@end

@implementation DBGStopwatch

+ (NSMutableDictionary *)watches {
    static NSMutableDictionary *Watches = nil;
    static dispatch_once_t OnceToken;
    dispatch_once(&OnceToken, ^{
        Watches = @{}.mutableCopy;
    });
    return Watches;
}

+ (double)secondsFromMachTime:(uint64_t)time {
    mach_timebase_info_data_t timebase;
    mach_timebase_info(&timebase);
    return (double)time * (double)timebase.numer /
        (double)timebase.denom / 1e9;
}

+ (void)start:(NSString *)name {
    uint64_t begin = mach_absolute_time();
    self.watches[name] = @(begin);
}

+ (void)stop:(NSString *)name {
    uint64_t end = mach_absolute_time();
    uint64_t begin = [self.watches[name] unsignedLongLongValue];
    DDLogInfo(@"Time taken for %@ %g s",
              name, [self secondsFromMachTime:(end - begin)]);
    [self.watches removeObjectForKey:name];
}

@end
Run Code Online (Sandbox Code Playgroud)

它的使用非常简单:

  • [DBGStopwatch start:@"slow-operation"];一开始就打电话
  • 然后[DBGStopwatch stop:@"slow-operation"];在完成后,得到时间