Как регистрировать время выполнения метода точно в миллисекундах?

Есть ли способ определить, сколько времени нужно для выполнения метода (в миллисекундах)?


person dan    schedule 25.01.2010    source источник
comment
Вы случайно не спрашиваете, потому что хотите узнать, что можно оптимизировать, чтобы сделать это быстрее?   -  person Mike Dunlavey    schedule 25.01.2010
comment
Да, я использую UIWebView, который загружает несколько страниц. Я хочу оптимизировать загрузку страниц, проверяя время, необходимое методу для загрузки страницы с 1 по 10.   -  person dan    schedule 25.01.2010
comment
Похоже, это дубликат этого вопроса: stackoverflow.com/questions/889380/   -  person Brad Larson    schedule 25.01.2010
comment
@BradLarson Хотя это кажется дубликатом, другой вопрос имеет лучшие ответы, т.е. там известные ответы не предлагают использовать (неправильный) NSDate, а вместо этого хорошо объясняют, почему NSDate - неправильный способ для этой цели.   -  person Thomas Tempelmann    schedule 04.06.2016


Ответы (19)


NSDate *methodStart = [NSDate date];

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

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

Swift:

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)")

Прост в использовании и имеет точность до долей миллисекунды.

person Matthew McGoogan    schedule 25.01.2010
comment
Значение возвращается в секундах? - person Peter Warbo; 07.07.2011
comment
@PeterWarbo NSTimeInterval - это определение типа double и определяется как секунды - см. developer.apple.com/library/mac/#documentation/Cocoa/Reference/. - person Ben Lings; 03.11.2011
comment
Вы можете зарегистрировать это значение с помощью% f - NSLog (executionTime =% f, executionTime); - person Tony; 16.01.2012
comment
@ Тони, ты забыл @, NSLog(@"executionTime = %f", executionTime); - person John Riselvato; 18.04.2013
comment
Я только что сравнил NSDate и mach_absolute_time() на уровне 30 мс. 27 против 29, 36 против 39, 43 против 45. NSDate было легче использовать для меня, и результаты были достаточно похожими, чтобы не беспокоиться о mach_absolute_time(). - person nevan king; 01.08.2013
comment
Все, что основано на NSDate, небезопасно для измерения прошедшего времени, потому что время может прыгать даже в обратном направлении. Гораздо более безопасный способ - использовать mach_absolute_time, как показано во многих других ответах здесь. Это должно быть проигнорировано как плохой пример. См. Также соответствующий ответ, в котором все это объясняется более подробно: stackoverflow.com/a/30363702/43615 - person Thomas Tempelmann; 04.06.2016
comment
Быстрый однострочник: NSLog("Total time: %f", NSDate().timeIntervalSinceDate(methodStart)) - person Tom Roggero; 08.06.2016
comment
Или просто сделайте NSDate *startDate = [NSDate date]; // action; [startDate timeIntervalSinceNow] - person Daneo; 01.07.2016
comment
Для более точного отсчета времени вы можете использовать CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); Поскольку CFAbsoluteTime double, он очень точный (вероятно, намного больше, чем вам нужно), но его удобно использовать: вы получаете результат уже в секундах (с десятичными знаками), поэтому нет необходимости конвертировать. - person thetrutz; 29.09.2016
comment
Все еще золотой ответ в 2017 году - person ; 13.03.2017
comment
чтобы получить результат действительно в MS без секунд (только миллисекунды): stackoverflow.com/a/49140242/7767664 - person user924; 07.03.2018
comment
@thetrutz CFAbsoluteTimeGetCurrent небезопасен, как и NSDate для сравнительного анализа - person Alex Nazarov; 22.10.2020
comment
@AlexNazarsky, пожалуйста, уточнить. Проблема с NSDate в том, что он выделяет объект, что очень медленно (200–300 нс?), Тогда как CFAbsoluteTimeGetCurrent () этого не делает. Но, честно говоря, я не тестировал, а получил эту информацию от: M. Weiher: Настройка производительности iOS и macOS. - person thetrutz; 23.10.2020
comment
@thetrutz проблема в том, что NSDate зависит от часовых поясов, перехода на летнее время, дополнительных секунд и т.д., в отличие от mach_absolute_time / CACurrentMediaTime. - person Alex Nazarov; 28.10.2020
comment
@AlexNazarsky Я не могу следить за вашими ответами. Вы сказали, что CFAbsoluteTimeGetCurrent небезопасен, интересно, почему? Вы сказали, NSDate зависит от часовых поясов. Но это не так. Он представляет собой момент времени с лежащим в основе Double (секунды с контрольной даты). Таким образом, он содержит ту же информацию, что и двойное значение из CFAbsoluteTimeGetCurrent, но вместо того, чтобы быть Double NSDate, это объекты, которым требуется время для выделения, которое является медленным (в наносекундах) и может повлиять на ваши измерения, тогда как CFAbsoluteTimeGetCurrent просто возвращает двойное без дополнительное выделение. - person thetrutz; 29.10.2020
comment
@thetrutz 1. Это явно описано здесь developer.apple.com/documentation/corefoundation/ 2. Вы можете просто проверить это - вывести значения CFAbsoluteTimeGetCurrent и CACurrentMediaTime, изменить системную дату (например) и снова проверить. В первом случае вы получите отрицательное количество секунд, во втором - фактическое значение. - person Alex Nazarov; 30.10.2020
comment
@AlexNazarsky, что тебе за объяснение! Подводя итог: CFAbsoluteTimeGetCurrent небезопасен, когда системные часы устанавливаются пользователем или через сервер времени (редко). CACurrentMediaTime небезопасен, когда устройство переводится в спящий режим (редко). NSDate - это плохо из-за времени выделения. NSDate не зависит от дополнительных секунд / часовых поясов / перехода на летнее время - то есть того, для чего предназначен календарь. - person thetrutz; 31.10.2020

Вот два однострочных макроса, которые я использую:

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

Используйте это так:

TICK;

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

TOCK;
person Ron    schedule 01.04.2013
comment
Что делает его таким хорошим, так это то, что тик-так - такая запоминающаяся фраза, что ведение журнала почти не требует размышлений. - person John Riselvato; 07.02.2014
comment
#define TOCK NSLog(@"%s Time: %f", __func__, -[startTime timeIntervalSinceNow]) заставляет этот ответ также возвращать, в какой функции использовался таймер. Я нашел это полезным, если бы использовал TICK TOCK для измерения времени нескольких функций. - person golmschenk; 14.03.2014
comment
Отличная идея @golmschenk! Вы также можете изучить __PRETTY_FUNCTION__ и __LINE__, если вам нужна более подробная информация. - person Ron; 17.03.2014
comment
Tick ​​/ Tock - это круто, но лучше не использовать NSDate для точного определения времени. - person thetrutz; 02.11.2020

Для точной синхронизации в 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;

Конечно, применимы обычные предостережения относительно точных измерений; вам, вероятно, лучше всего вызывать тестируемую процедуру много раз и усреднять / брать минимум / какую-то другую форму обработки.

Кроме того, обратите внимание, что вы можете найти более полезным профилировать свое приложение, работающее с помощью такого инструмента, как Shark. Это не даст вам точной информации о времени, но покажет, какой процент времени приложения тратится где, что часто более полезно (но не всегда).

person Stephen Canon    schedule 25.01.2010
comment
Пытаться заставить это работать в Swift ... есть предложения? - person zumzum; 16.01.2015
comment
Нельзя просто ... преобразовать в Swift - Нед Старк - person stonedauwg; 21.08.2015
comment
@zumzum См. мой ответ для примера того, как это сделать в Swift. - person jbg; 15.08.2018

Для mach_absolute_time() есть удобная обертка - это CACurrentMediaTime() функция.

В отличие от смещений NSDate или CFAbsoluteTimeGetCurrent(), mach_absolute_time() и CACurrentMediaTime() основаны на внутренних часах хоста, точном, одноатомном измерении и не подвержены изменениям во внешней привязке времени, например, вызванным часовыми поясами, переходом на летнее время или дополнительными секундами.


ObjC

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

Swift

let startTime = CACurrentMediaTime()
// Do your stuff here
let endTime = CACurrentMediaTime()
print("Total Runtime: \(endTime - startTime) s")
person Alex Nazarov    schedule 21.12.2018
comment
Я думаю, что этот ответ заслуживает большего количества голосов. Это лучше, чем использовать NSDate. - person average Joe; 14.05.2019
comment
Это то же самое, что и CFAbsoluteTimeGetCurrent ()? Его переименовали? - person Ezekiel Elin; 21.10.2020
comment
@EzekielElin - нет, CFAbsoluteTimeGetCurrent может уменьшиться из-за синхронизации с внешними привязками времени или из-за явного изменения часов пользователем в соответствии с документацией Apple, поэтому он не подходит для тестирования - person Alex Nazarov; 22.10.2020

В 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()

Swift 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)")
}
  • этот код основан на переводе кода Рона на Swift, у него есть кредиты
  • Я использую дату начала на глобальном уровне, любые предложения по улучшению приветствуются
person Adriano Spadoni    schedule 22.01.2015
comment
Это должно быть \(-startTime.timeIntervalSinceNow) (обратите внимание на негатив) - person Snowman; 09.01.2016

Я знаю, что это старый, но даже я обнаружил, что снова блуждаю мимо него, поэтому я подумал, что представлю здесь свой собственный вариант.

Лучше всего проверить мое сообщение в блоге по этому поводу: Расчет времени в Цель-C: секундомер

По сути, я написал класс, который перестает смотреть в очень простом виде, но инкапсулирован, так что вам нужно только сделать следующее:

[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];

И вы получите:

MyApp[4090:15203]  -> Stopwatch: [My Timer] runtime: [0.029]

в журнале ...

Опять же, ознакомьтесь с моим сообщением, чтобы узнать больше, или загрузите его здесь: MMStopwatch.zip

person bladnman    schedule 24.01.2012

Я использую макросы на основе решения Рона.

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

Для строк кода:

TICK(TIME1);
/// do job here
TOCK(TIME1);

мы увидим в консоли что-то вроде: TIME1: 0.096618

person Sergey Teryokhin    schedule 25.01.2016
comment
Ваш ответ на самом деле не так уж сильно отличается от ответа Рона, и я почему-то не вижу, в чем он лучше? - person Trilarion; 26.01.2016
comment
Вы не можете использовать решение @Ron в одном контексте дважды. Это основная причина появления макросов. - person Sergey Teryokhin; 26.01.2016


Я использую этот код:

#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;
}
person cleexiang    schedule 18.05.2015

Вы можете получить действительно точное время (секунды, доли секунды) с помощью этого класса StopWatch. В iPhone используется высокоточный таймер. Использование NSDate даст вам только секунду (-ы) точности. Эта версия разработана специально для autorelease и 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, чтобы остановить это. Вы все еще можете узнать время (позвонить seconds) в любое время после вызова stop.

Пример в функции (время вызова выполнения)

-(void)SomeFunc
{
   StopWatch* stopWatch = [StopWatch stopWatch];
   [stopWatch Start];

   ... do stuff

   [stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}
person FuzzyBunnySlippers    schedule 02.01.2014
comment
Ваша точность до секунд неверна. Хотя вся часть NSTimeInterval составляет секунды, это двойная величина. - person Steven Fisher; 02.01.2017

Я использую это:

clock_t start, end;
double elapsed;
start = clock();

//Start code to time

//End code to time

end = clock();
elapsed = ((double) (end - start)) / CLOCKS_PER_SEC;
NSLog(@"Time: %f",elapsed);

Но я не уверен насчет CLOCKS_PER_SEC на iPhone. Вы можете оставить его выключенным.

person David Kanarek    schedule 25.01.2010
comment
CLOCKS_PER_SEC на iPhone - очень неточное значение. - person mxcl; 13.03.2011
comment
Хорошо знать. Я бы использовал ответ Мэтью, если бы мне пришлось сделать это сейчас. - person David Kanarek; 13.03.2011

Пример точной синхронизации с использованием mach_absolute_time() в Swift 4:

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")
}
person jbg    schedule 15.08.2018

Хорошо, если ваша цель - выяснить, что вы можете исправить, чтобы сделать это быстрее, это немного другая цель. Измерение времени, затрачиваемого на выполнение функций, - хороший способ выяснить, изменилось ли то, что вы сделали, но чтобы выяснить, что делать, вам понадобится другой метод. Это то, что я рекомендую, и я знаю, что вы можете сделать это на айфонах.

Изменить: рецензенты предложили мне уточнить ответ, поэтому я пытаюсь придумать краткий способ сказать это.
Ваша общая программа занимает достаточно времени, чтобы вас беспокоить. Предположим, это N секунд.
Вы предполагаете, что можете ускорить это. Единственный способ сделать это - заставить его не делать за это время то, что он делает, с учетом m секунд.
Вы изначально не знаете, что это за штука. Вы можете догадываться, как и все программисты, но это может быть что-то еще. Что бы это ни было, вот как вы можете это найти:

Поскольку эта штука, какой бы она ни была, составляет долю m / N времени, это означает, что если вы приостановите ее наугад, вероятность того, что вы поймаете, составит m / N это в процессе выполнения этой вещи. Конечно, он может делать что-то еще, но остановите его и посмотрите, что он делает.
А теперь сделайте это снова. Если вы снова увидите, что он делает то же самое, вы можете быть более подозрительными.

Сделайте это 10 раз или 20. Теперь, если вы видите, что он делает что-то особенное (неважно, как вы это описываете) в течение нескольких пауз, от которых вы можете избавиться, вы знаете две вещи. Вы очень приблизительно знаете, сколько времени потребуется, но вы знаете очень точно, что нужно исправить.
Если вы также хотите знать очень точно, сколько времени будет спасено, это просто. Измерьте его до, исправьте и измерьте после. Если вы действительно разочарованы, откажитесь от исправления.

Вы видите, чем это отличается от измерения? Это поиск, а не измерение. Большинство профилирований основано на максимально точном измерении того, сколько времени требуется, как будто это важно, и решает проблему определения того, что необходимо исправить. Профилирование не позволяет найти все проблемы, но этот метод обнаруживает все проблемы, и именно проблемы, которые вы не находите, причиняют вам боль.

person Mike Dunlavey    schedule 25.01.2010

Вот еще один способ сделать это в Swift с помощью ключевого слова defer

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

Из Apple документы: Оператор defer используется для выполнения кода непосредственно перед передачей управления программой за пределы области действия, в которой находится оператор defer.

Это похоже на блок try / finally с тем преимуществом, что связанный код сгруппирован.

person CMont    schedule 27.12.2016

Я использую это в своей библиотеке утилит (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 выше, но достаточно ясно, чтобы увидеть, что он делает, и автоматически включает то, что рассчитывается по времени (по файлу, строке в начале метода и имени функции). Очевидно, что если мне нужно больше подробностей (например, если я не просто синхронизирую вызов метода, как обычно, а вместо этого синхронизирую блок внутри этого метода), я могу добавить параметр «name =" Foo "» в инициализацию PrintTimer чтобы назвать это чем-то помимо значений по умолчанию.

person Tom Dibble    schedule 09.07.2018

Поскольку вы хотите оптимизировать время перехода с одной страницы на другую в UIWebView, не означает ли это, что вы действительно хотите оптимизировать Javascript, используемый при загрузке этих страниц?

С этой целью я бы посмотрел на профилировщик WebKit, о котором говорилось здесь:

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

Другой подход - начать с высокого уровня и подумать, как можно разработать соответствующие веб-страницы, чтобы минимизировать время загрузки, используя загрузку страницы в стиле AJAX вместо того, чтобы каждый раз обновлять весь веб-просмотр.

person Kendall Helmstetter Gelner    schedule 25.01.2010

Вот решение 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.Instrumentation (заголовок: «Начать просмотр с загрузкой», точка: 1, elapsedTime: 0,040504038333892822), MyApp.SomeViewController.Instrumentation (заголовок: «Завершенное добавление вложенных представлений», точка: 2, истекшее время: 0,010585010051729 MyApp.SomeViewController.Instrumentation (заголовок: «Просмотр появился», точка: 3, elapsedTime: 0,56564098596572876)]

person markhorrocks    schedule 14.06.2017

многие ответы странные и на самом деле не дают результата в миллисекундах (но в секундах или чем-то еще):

вот что я использую, чтобы получить MS (МИЛЛИСЕКУНД):

Swift:

let startTime = NSDate().timeIntervalSince1970 * 1000

// your Swift code

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

Цель-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 );
person user924    schedule 06.03.2018

Для Swift 4 добавьте в качестве делегата в свой класс:

public protocol TimingDelegate: class {
    var _TICK: Date?{ get set }
}

extension TimingDelegate {
    var TICK: Date {
        _TICK = Date()
        return(_TICK)!
     }

    func TOCK(message: String)  {

        if (_TICK == nil){
            print("Call 'TICK' first!")
        }

        if (message == ""){
            print("\(Date().timeIntervalSince(_TICK!))")
        }
        else{
            print("\(message): \(Date().timeIntervalSince(_TICK!))")
        }
    }
}

Добавьте в наш класс:

class MyViewcontroller: UIViewController, TimingDelegate

Затем добавьте в свой класс:

var _TICK: Date?

Если вы хотите что-то рассчитать, начните с:

TICK

И в конце:

TOCK("Timing the XXX routine")
person Snickitybit    schedule 19.03.2018
comment
Вы читали ответы и комментарии? Не используйте для этого Date! - person matt; 19.03.2018