是否有一种方法可以确定一个方法需要执行多少时间(以毫秒为单位)?
当前回答
一个在Swift 4中使用mach_absolute_time()的细粒度计时的例子:
let start = mach_absolute_time()
// do something
let elapsedMTU = mach_absolute_time() - start
var timebase = mach_timebase_info()
if mach_timebase_info(&timebase) == 0 {
let elapsed = Double(elapsedMTU) * Double(timebase.numer) / Double(timebase.denom)
print("render took \(elapsed)")
}
else {
print("timebase error")
}
其他回答
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)")
易于使用,具有亚毫秒精度。
对于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等工具对应用程序运行进行概要分析更有用。这不会为您提供确切的时间信息,但它会告诉您应用程序的时间在哪里花费了多少百分比,这通常更有用(但并不总是如此)。
这里有另一种方法,在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块,优点是将相关代码分组。
你可以得到很好的时间(秒。部分秒)使用这个StopWatch类。它使用了iPhone的高精度计时器。使用NSDate只能获得秒级精度。这个版本是专门为自动发布和objective-c设计的。如果需要的话,我也有一个c++版本。你可以在这里找到c++版本。
StopWatch.h
#import <Foundation/Foundation.h>
@interface StopWatch : NSObject
{
uint64_t _start;
uint64_t _stop;
uint64_t _elapsed;
}
-(void) Start;
-(void) Stop;
-(void) StopWithContext:(NSString*) context;
-(double) seconds;
-(NSString*) description;
+(StopWatch*) stopWatch;
-(StopWatch*) init;
@end
StopWatch.m
#import "StopWatch.h"
#include <mach/mach_time.h>
@implementation StopWatch
-(void) Start
{
_stop = 0;
_elapsed = 0;
_start = mach_absolute_time();
}
-(void) Stop
{
_stop = mach_absolute_time();
if(_stop > _start)
{
_elapsed = _stop - _start;
}
else
{
_elapsed = 0;
}
_start = mach_absolute_time();
}
-(void) StopWithContext:(NSString*) context
{
_stop = mach_absolute_time();
if(_stop > _start)
{
_elapsed = _stop - _start;
}
else
{
_elapsed = 0;
}
NSLog([NSString stringWithFormat:@"[%@] Stopped at %f",context,[self seconds]]);
_start = mach_absolute_time();
}
-(double) seconds
{
if(_elapsed > 0)
{
uint64_t elapsedTimeNano = 0;
mach_timebase_info_data_t timeBaseInfo;
mach_timebase_info(&timeBaseInfo);
elapsedTimeNano = _elapsed * timeBaseInfo.numer / timeBaseInfo.denom;
double elapsedSeconds = elapsedTimeNano * 1.0E-9;
return elapsedSeconds;
}
return 0.0;
}
-(NSString*) description
{
return [NSString stringWithFormat:@"%f secs.",[self seconds]];
}
+(StopWatch*) stopWatch
{
StopWatch* obj = [[[StopWatch alloc] init] autorelease];
return obj;
}
-(StopWatch*) init
{
[super init];
return self;
}
@end
该类有一个返回自动释放对象的静态stopWatch方法。
调用start后,使用seconds方法获取运行时间。再次调用start来重新启动它。或者停下来停下来。在调用stop后,您仍然可以随时读取时间(调用秒数)。
函数中的示例(执行的定时调用)
-(void)SomeFunc
{
StopWatch* stopWatch = [StopWatch stopWatch];
[stopWatch Start];
... do stuff
[stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}
struct TIME {
static var ti = mach_timebase_info()
static var k: Double = 1
static var mach_stamp: Double {
if ti.denom == 0 {
mach_timebase_info(&ti)
k = Double(ti.numer) / Double(ti.denom) * 1e-6
}
return Double(mach_absolute_time()) * k
}
static var stamp: Double { return NSDate.timeIntervalSinceReferenceDate() * 1000 }
}
do {
let mach_start = TIME.mach_stamp
usleep(200000)
let mach_diff = TIME.mach_stamp - mach_start
let start = TIME.stamp
usleep(200000)
let diff = TIME.stamp - start
print(mach_diff, diff)
}
推荐文章
- 点击按钮时如何打开手机设置?
- 如何使用UIVisualEffectView来模糊图像?
- 如何修复UITableView分隔符在iOS 7?
- 故事板中的自定义单元格行高设置没有响应
- 如何改变时间和时区在iPhone模拟器?
- 在Swift中使用自定义消息抛出错误/异常的最简单方法?
- 如何在Swift中获得唯一的设备ID ?
- 我如何知道何时UITableView完成了ReloadData?
- 复制文本到剪贴板与iOS
- 在Swift中根据字符串计算UILabel的大小
- 如何调用手势点击在UIView编程在迅速
- 什么是Swift相当于respondsToSelector?
- 如何检查NSString是否以某个字符开始
- 我如何隐藏在一个Swift iOS应用程序的状态栏?
- 在iPad上使用iOS 8正确呈现UIAlertController