Até onde eu sei, existem pelo menos dez maneiras de medir o tempo decorrido:
Relógio monotônico baseado:
ProcessInfo.systemUptime
.
mach_absolute_time
com mach_timebase_info
como mencionado nesta resposta .
clock()
no padrão POSIX .
times()
no padrão POSIX . (Muito complicado, pois precisamos considerar o tempo do usuário versus o tempo do sistema, e os processos filhos estão envolvidos.)
DispatchTime
(um invólucro em torno da API do horário do Mach), conforme mencionado por JeremyP na resposta aceita.
CACurrentMediaTime()
.
Relógio de parede baseado:
(nunca use esses para métricas: veja abaixo o porquê)
NSDate
/ Date
como mencionado por outros.
CFAbsoluteTime
como mencionado por outros.
DispatchWallTime
.
gettimeofday()
no padrão POSIX .
As opções 1, 2 e 3 são elaboradas abaixo.
Opção 1: API de informações do processo no Foundation
do {
let info = ProcessInfo.processInfo
let begin = info.systemUptime
// do something
let diff = (info.systemUptime - begin)
}
onde diff:NSTimeInterval
é o tempo decorrido em segundos.
Opção 2: API Mach C
do {
var info = mach_timebase_info(numer: 0, denom: 0)
mach_timebase_info(&info)
let begin = mach_absolute_time()
// do something
let diff = Double(mach_absolute_time() - begin) * Double(info.numer) / Double(info.denom)
}
onde diff:Double
é o tempo decorrido em nanossegundos.
Opção 3: API do relógio POSIX
do {
let begin = clock()
// do something
let diff = Double(clock() - begin) / Double(CLOCKS_PER_SEC)
}
onde diff:Double
é o tempo decorrido em segundos.
Por que não o tempo do relógio de parede pelo tempo decorrido?
Na documentação de CFAbsoluteTimeGetCurrent
:
Chamadas repetidas para esta função não garantem resultados crescentes monotonicamente.
O motivo é semelhante ao currentTimeMillis
vs nanoTime
em Java :
Você não pode usar esse para o outro propósito. A razão é que o relógio do computador não é perfeito; sempre deriva e, ocasionalmente, precisa ser corrigido. Essa correção pode ocorrer manualmente ou, no caso da maioria das máquinas, existe um processo que executa e emite continuamente pequenas correções no relógio do sistema ("relógio de parede"). Estes tendem a acontecer frequentemente. Outra correção desse tipo ocorre sempre que há um salto de segundo.
Aqui CFAbsoluteTime
fornece a hora do relógio de parede em vez da hora de inicialização. NSDate
é a hora do relógio de parede também.
sqrt(number)
vez denumber
e você pode economizar um pouco mais de tempo - mas há muito mais idéias para otimizar a busca por números primos.