Jak zapisać czas wykonania metody dokładnie w milisekundach?

Czy istnieje sposób, aby określić, ile czasu metoda musi wykonać (w milisekundach)?

Author: Kara, 2010-01-25

20 answers

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

Łatwy w użyciu i ma dokładność poniżej milisekundy.

 445
Author: Matthew McGoogan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 14:05:22

Oto dwa jednoliniowe makra, których używam:

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

Użyj go tak:

TICK;

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

TOCK;
 253
Author: Ron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-01 09:01:07

Dla drobnoziarnistego czasu na OS X, należy użyć mach_absolute_time( ) zadeklarowanego w <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;

Oczywiście stosuje się zwykłe zastrzeżenia dotyczące drobnoziarnistych pomiarów; prawdopodobnie najlepiej będzie wielokrotnie odwoływać się do testowanej procedury i uśredniać / brać minimum / jakąś inną formę przetwarzania.

Dodatkowo, należy pamiętać, że może okazać się bardziej przydatne profil Twoja aplikacja działa przy użyciu narzędzia takiego jak Shark. To nie da Ci dokładnych informacji o czasie, ale będzie powiedz jaki procent czasu aplikacji jest spędzany gdzie, co jest często bardziej przydatne (ale nie zawsze).

 52
Author: Stephen Canon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-25 02:11:48

Istnieje wygodny wrapper dla mach_absolute_time() – jest to CACurrentMediaTime() funkcja.

W przeciwieństwie do NSDate lub CFAbsoluteTimeGetCurrent() offsetów, mach_absolute_time() i CACurrentMediaTime() są oparte na wewnętrzny zegar hosta, dokładna, monatomowa miara, nie podlegająca zmiany w odniesieniu do czasu zewnętrznego, takie jak te spowodowane przez czas strefy, czas letni lub sekundy przestępne.


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")
 32
Author: Alex Nazarsky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-21 17:52:55

W Swift używam:

W moich makrach.swift I just added
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)")
}
Teraz możesz zadzwonić wszędzie]}
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)")
}
  • ten kod jest oparty na kodzie Rona przetłumaczonym na Swift, on ma napisy
  • używam daty rozpoczęcia na poziomie globalnym, wszelkie sugestie poprawy są mile widziane
 12
Author: Adriano Spadoni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-10 04:58:55

Wiem, że to jest stary, ale nawet ja znalazłem się błąkając się po nim ponownie, więc pomyślałem, że przedstawię własną opcję tutaj.

Najlepiej sprawdzić mój wpis na blogu na ten: Timing rzeczy w Objective-C: stoper

W zasadzie napisałem klasę, która w bardzo prosty sposób przestaje oglądać, ale jest zamknięta tak, że wystarczy wykonać następujące czynności:

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

I kończy się na:

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

W dzienniku...

Ponownie, sprawdź mój post dla trochę więcej lub pobierz go tutaj: MMStopwatch.zip

 9
Author: bladnman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-24 19:37:58

Używam makr opartych na rozwiązaniu Rona .

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

Dla linii kodu:

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

Zobaczymy w konsoli coś w stylu: TIME1: 0.096618

 7
Author: Sergey Teryokhin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:12

Używam bardzo minimalnej, jednostronicowej implementacji klasy zainspirowanej kodem z tego posta na blogu :

#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

Użycie tego jest bardzo proste:

  • po prostu zadzwoń [DBGStopwatch start:@"slow-operation"]; na początku
  • a następnie [DBGStopwatch stop:@"slow-operation"]; po zakończeniu, aby uzyskać CZAS
 5
Author: zubko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-30 09:20:55

Używam tego kodu:

#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;
}
 4
Author: cleexiang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 10:28:05

Możesz uzyskać naprawdę fine timing (seconds.części sekund) za pomocą tej klasy stopera. Wykorzystuje precyzyjny timer w iPhonie. Korzystanie z NSDate zapewni Ci tylko sekundę (s) dokładności. Ta wersja jest zaprojektowana specjalnie dla autorelease i objective-c. w razie potrzeby mam również wersję c++. możesz znaleźć wersję c++ tutaj .

Stoper.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

Stoper.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

Klasa ma statyczną stopWatch metoda zwracająca obiekt z automatycznym odczytem.

Po wywołaniu start użyj metody seconds, aby uzyskać czas, który upłynął. Zadzwoń ponownie start, aby go ponownie uruchomić. Albo stop, aby to powstrzymać. Możesz odczytać czas (call seconds) w każdej chwili po wywołaniu stop.

Przykład w funkcji (wywołanie czasu wykonania)

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

   ... do stuff

   [stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}
 3
Author: FuzzyBunnySlippers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-02 13:46:56

Używam tego:

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

Ale nie jestem pewien co do CLOCKS_PER_SEC na iPhonie. Lepiej to zostaw.

 2
Author: David Kanarek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-25 02:10:07

Przykład drobnoziarnistego pomiaru czasu za pomocą mach_absolute_time() W 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")
}
 2
Author: jbg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 04:42:52

OK, jeśli twoim celem jest dowiedzieć się, co możesz naprawić, aby było szybciej, to jest trochę inny cel. Pomiar czasu, który zajmuje funkcje, jest dobrym sposobem, aby dowiedzieć się, czy to, co zrobiłeś, zrobiło różnicę, ale aby dowiedzieć się, co zrobić, potrzebujesz innej techniki. to jest to, co polecam , i Wiem, że można to zrobić na iPhone ' ach.

Edit: Recenzenci zasugerowali mi rozwinięcie odpowiedzi, więc staram się wymyślić krótki sposób, aby to powiedzieć.
Twój ogólny program zajmuje wystarczająco dużo czasu, żeby ci przeszkadzać. Załóżmy, że jest to N sekund.
Zakładasz, że możesz to przyspieszyć. Jedynym sposobem, aby to zrobić, jest uczynienie go nie robić czegoś, co robi w tym czasie, licząc m sekund.
Nie wiesz, co to jest. Można się domyślać, jak wszyscy programiści, ale może to być coś innego. Cokolwiek to jest, oto jak możesz to znaleźć:

Ponieważ to coś, cokolwiek to jest, stanowi ułamek M / N czasu, oznacza to, że jeśli zatrzymasz go losowo, prawdopodobieństwo jest m / N, że złapiesz go w akcie robienia tej rzeczy. Oczywiście może to robić coś innego, ale zatrzymaj to i zobacz, co robi.
Zrób to jeszcze raz. Jeśli zobaczysz, że robi to samo ponownie, możesz być bardziej podejrzliwy.

Zrób to 10 razy, albo 20. Jeśli widzicie, że robi jakąś konkretną rzecz (bez względu na to, jak to opisujecie) przy wielu pauzach, których możecie się pozbyć, znacie dwie rzeczy. Wiesz bardzo z grubsza jaki ułamek czasu to zajmuje, ale wiesz bardzo dokładnie Co naprawić.
Jeśli chcesz również wiedzieć bardzo dokładnie Ile czasu zostanie zaoszczędzony, to proste. Zmierz go przed, napraw i zmierz po. Jeśli jesteś naprawdę rozczarowany, wycofaj się z naprawy.

Widzisz czym to się różni od pomiaru? To znajdowanie, nie mierzenie . Większość profilowania opiera się na pomiarze jak najdokładniej, ile czasu zajmuje, jakby to było ważne i ręka-fale problem identyfikacji, co należy naprawić. Profilowanie nie znajduje każdego problemu, ale ta metoda znajduje każdy problem, a to problemy, których nie znajdziesz, ranią cię.

 2
Author: Mike Dunlavey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-28 16:35:40

Oto inny sposób, w języku Swift, aby to zrobić za pomocą słowa kluczowego defer

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

Z dokumentów Apple: Instrukcja defer jest używana do wykonywania kodu tuż przed przeniesieniem kontroli programu poza zakres, w którym pojawia się instrukcja defer.

Jest to podobne do bloku try/finally z tą zaletą, że powiązany kod jest zgrupowany.

 0
Author: CMont,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-27 04:52:18

Używam tego w mojej bibliotece 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.")
    }
}

... następnie wywołaj metodę taką jak:

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

... co z kolei wygląda tak w konsoli po uruchomieniu:

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

Nie jest tak zwięzły jak Tick / TOCK powyżej, ale jest wystarczająco jasny, aby zobaczyć, co robi i automatycznie Zawiera to, co jest timed (przez plik, linię na początku metody i nazwę funkcji). Oczywiście, jeśli chciałem więcej szczegółów (ex, jeśli nie jestem tylko czas wywołania metody jak zwykle przypadku, ale zamiast tego jestem timing bloku w tej metodzie) Mogę dodać parametr"name=" Foo" " na printtimer init aby nazwać to coś oprócz domyślnych.

 0
Author: Tom Dibble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-09 23:23:39

Ponieważ chcesz zoptymalizować czas przechodzenia z jednej strony na drugą w UIWebView, nie oznacza to, że naprawdę chcesz zoptymalizować Javascript używany do ładowania tych stron?

W tym celu rzuciłbym okiem na taki Profiler Webkitowy:

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

Innym podejściem byłoby zacząć na wysokim poziomie i zastanowić się, jak można zaprojektować strony internetowe, o których mowa aby zminimalizować czas ładowania za pomocą stylu AJAX ładowanie strony zamiast odświeżania całego widoku sieci Web za każdym razem.

 -1
Author: Kendall Helmstetter Gelner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-25 02:52:06
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)
}
 -1
Author: user3441734,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 22:15:38

Oto rozwiązanie Swift 3 do bisectingu kodu w dowolnym miejscu, aby znaleźć długo działający proces.

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

Użycie: -

instrument("View Did Appear")

print("ELAPSED TIMES \(elapsedTimes)")

Przykładowe wyjście:-

Upłynęły czasy [MyApp.SomeViewController.Oprzyrządowanie(tytuł: "Widok startowy Did Load", point: 1, elapsedTime: 0.040504038333892822), MyApp.SomeViewController.Instrumentacja (tytuł: "zakończone dodawanie SubViews", point: 2, elapsedTime: 0.010585010051727295), MyApp.SomeViewController.Instrumentacja(tytuł: "Wyświetlono", point: 3, elapsedTime: 0.56564098596572876)]

 -1
Author: markhorrocks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-15 00:14:36

Wiele odpowiedzi jest dziwnych i tak naprawdę nie dają wyniku w milisekundach (ale w sekundach lub cokolwiek innego):

Oto czego używam, aby uzyskać MS (milisekundy):

Swift:

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 );
 -1
Author: user924,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-06 21:35:03

Dla Swift 4 Dodaj jako delegata do swojej klasy:

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

Dodaj do Naszej Klasy:

class MyViewcontroller: UIViewController, TimingDelegate

Następnie dodaj do swojej klasy:

var _TICK: Date?

Kiedy chcesz coś odmierzyć, zacznij od:

TICK

I kończy się na:

TOCK("Timing the XXX routine")
 -1
Author: Snickitybit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-19 02:16:31