ios - reloj - tiempo ejecucion c#
¿Cómo registrar el tiempo de ejecución de un método exactamente en milisegundos? (19)
¿Hay una manera de determinar cuánto tiempo necesita ejecutar un método (en milisegundos)?
Aquí hay dos macros de una línea que utilizo:
#define TICK NSDate *startTime = [NSDate date]
#define TOCK NSLog(@"Time: %f", -[startTime timeIntervalSinceNow])
Úsalo así:
TICK;
/* ... Do Some Work Here ... */
TOCK;
Aquí hay otra forma, en Swift, de hacer eso usando la palabra clave deferir
func methodName() {
let methodStart = Date()
defer {
let executionTime = Date().timeIntervalSince(methodStart)
print("Execution time: /(executionTime)")
}
// do your stuff here
}
De los docs de Apple: se usa una declaración de aplazamiento para ejecutar el código justo antes de transferir el control del programa fuera del alcance en el que aparece la declaración de aplazamiento.
Esto es similar a un bloque try / finally con la ventaja de tener el código relacionado agrupado.
Aquí hay una solución Swift 3 para dividir el código en cualquier lugar para encontrar un proceso de larga ejecución.
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()
}
Uso: -
instrument("View Did Appear")
print("ELAPSED TIMES /(elapsedTimes)")
Salida de muestra: -
ELAPSED TIMES [MyApp.SomeViewController.Instrumentation (title: "Start View Did Load", punto: 1, elapsedTime: 0.040504038333892822), MyApp.SomeViewController.Instrumentation: ícono de la unidad de la cúpula de la trama de la cúpula de la jungla de la cúpula de la naturaleza. MyApp.SomeViewController.Instrumentation (título: "View Did Appear", punto: 3, elapsedTime: 0.56564098596572876)]
Dado que desea optimizar el tiempo de movimiento de una página a otra en un UIWebView, ¿no significa que realmente está buscando optimizar el Javascript utilizado para cargar estas páginas?
Para ello, me gustaría ver un perfil de WebKit como el que se habla aquí:
http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/
Otro enfoque sería comenzar en un nivel alto y pensar cómo puede diseñar las páginas web en cuestión para minimizar los tiempos de carga utilizando la carga de la página de estilo AJAX en lugar de actualizar la vista web completa cada vez.
De acuerdo, si su objetivo es descubrir qué puede arreglar para hacerlo más rápido, ese es un objetivo un poco diferente. Medir el tiempo que tardan las funciones es una buena manera de averiguar si lo que hizo marcó una diferencia, pero para saber qué hacer necesita una técnica diferente. Esto es lo que recomiendo , y sé que puedes hacerlo en iPhones.
En Swift, estoy usando:
En mi Macros.swift acabo de añadir
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)")
}
ahora puedes llamar a cualquier parte
TICK()
// your code to be tracked
TOCK()
- este código se basa en el código de Ron traducido a Swift, él tiene los créditos
- Estoy usando la fecha de inicio a nivel global, cualquier sugerencia para mejorar es bienvenida
Para Swift 4, agregue como Delegado a su clase:
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!))")
}
}
}
Añadir a nuestra clase:
class MyViewcontroller: UIViewController, TimingDelegate
Luego añada a su clase:
var _TICK: Date?
Cuando quieras cronometrar algo, comienza con:
TICK
Y termina con:
TOCK("Timing the XXX routine")
Para una sincronización mach_absolute_time( )
en OS X, debe usar mach_absolute_time( )
declarado en <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;
Por supuesto, se aplican las advertencias habituales sobre las mediciones de grano fino; Probablemente sea mejor invocar la rutina a prueba muchas veces y promediar / tomar un mínimo / alguna otra forma de procesamiento.
Además, tenga en cuenta que puede resultarle más útil crear un perfil de la aplicación que se ejecuta con una herramienta como Shark. Esto no le dará información exacta sobre el tiempo, pero le dirá qué porcentaje del tiempo de la aplicación se está gastando, lo que suele ser más útil (pero no siempre).
Puede obtener un tiempo realmente fino (segundos.parte de segundos) utilizando esta clase de StopWatch. Utiliza el temporizador de alta precisión en el iPhone. El uso de NSDate solo le dará una segunda (s) precisión. Esta versión está diseñada específicamente para autorelease y object-c. Tengo una versión c ++ también si es necesario. Puedes encontrar la versión de c ++ aquí .
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
La clase tiene un método stopWatch
estático que devuelve un objeto publicado automáticamente.
Una vez que start
llamada, use el método de seconds
para obtener el tiempo transcurrido. Llame a start
nuevamente para reiniciarlo. O stop
para detenerlo. Aún puede leer el tiempo ( seconds
llamada) en cualquier momento después de stop
llamada.
Ejemplo en una función (temporización de la llamada de ejecución)
-(void)SomeFunc
{
StopWatch* stopWatch = [StopWatch stopWatch];
[stopWatch Start];
... do stuff
[stopWatch StopWithContext:[NSString stringWithFormat:@"Created %d Records",[records count]]];
}
Sé que esto es antiguo, pero incluso me encontré vagando de nuevo, así que pensé en enviar mi propia opción aquí.
La mejor opción es revisar mi publicación de blog sobre esto: Programar cosas en Objective-C: Un cronómetro
Básicamente, escribí una clase que deja de ver de una manera muy básica pero está encapsulada de modo que solo necesitas hacer lo siguiente:
[MMStopwatchARC start:@"My Timer"];
// your work here ...
[MMStopwatchARC stop:@"My Timer"];
Y terminas con:
MyApp[4090:15203] -> Stopwatch: [My Timer] runtime: [0.029]
en el registro ...
De nuevo, echa un vistazo a mi publicación para un poco más o descárgala aquí: MMStopwatch.zip
Un ejemplo de tiempo de grano fino utilizando mach_absolute_time()
en 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")
}
Uso esto en mi biblioteca de 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.")
}
}
... entonces llama en un método como:
func myFunctionCall() {
let timer = PrintTimer()
// ...
timer.done()
}
... que a su vez se ve así en la consola después de ejecutarse:
MyFile.swift:225 - myFunctionCall() took 1.8623 s.
No es tan conciso como TICK / TOCK arriba, pero es lo suficientemente claro como para ver lo que está haciendo e incluye automáticamente lo que se está cronometrando (por archivo, línea al comienzo del método y nombre de la función). Obviamente, si quisiera más detalles (por ejemplo, si no estoy cronometrando una llamada de método como es el caso habitual, sino que estoy cronometrando un bloque dentro de ese método) puedo agregar el parámetro "name =" Foo "" en el inicio de PrintTimer Para nombrar algo más que los valores por defecto.
Uso una implementación de clase de una página muy mínima, inspirada en el código de esta publicación de blog :
#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
Su uso es muy sencillo:
- simplemente llame a
[DBGStopwatch start:@"slow-operation"];
al principio - y luego
[DBGStopwatch stop:@"slow-operation"];
Después de la finalización, para obtener el tiempo.
Yo uso este código:
#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;
}
Yo uso esto:
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);
Pero no estoy seguro sobre CLOCKS_PER_SEC en el iPhone. Es posible que desee dejarlo apagado.
Yo uso macros basadas en Ron''s solución Ron''s .
#define TICK(XXX) NSDate *XXX = [NSDate date]
#define TOCK(XXX) NSLog(@"%s: %f", #XXX, -[XXX timeIntervalSinceNow])
Para líneas de código:
TICK(TIME1);
/// do job here
TOCK(TIME1);
Veremos en consola algo como: TIEMPO1: 0.096618
muchas respuestas son raras y en realidad no dan resultados en milisegundos (pero en segundos o cualquier otra cosa):
Aquí lo que uso para obtener MS (MILLISECONDS):
Rápido:
let startTime = NSDate().timeIntervalSince1970 * 1000
// your Swift code
let endTimeMinusStartTime = NSDate().timeIntervalSince1970 * 1000 - startTime
print("time code execution /(endTimeMinStartTime) ms")
C objetivo:
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 );
NSDate *methodStart = [NSDate date];
/* ... Do whatever you need to do ... */
NSDate *methodFinish = [NSDate date];
NSTimeInterval executionTime = [methodFinish timeIntervalSinceDate:methodStart];
NSLog(@"executionTime = %f", executionTime);
Rápido:
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)")
Fácil de usar y tiene una precisión de menos de milisegundos.
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)
}