Comment mesurer le temps écoulé pour exécuter une fonction dans Swift? J'essaye d'afficher le temps écoulé comme ceci: "Le temps écoulé est de 0,05 seconde". Vu qu'en Java , nous pouvons utiliser System.nanoTime (), existe-t-il des méthodes équivalentes disponibles dans Swift pour y parvenir?
Veuillez consulter l'exemple de programme:
func isPrime(var number:Int) ->Bool {
var i = 0;
for i=2; i<number; i++ {
if(number % i == 0 && i != 0) {
return false;
}
}
return true;
}
var number = 5915587277;
if(isPrime(number)) {
println("Prime number");
} else {
println("NOT a prime number");
}
swift
time
nsdate
elapsedtime
Vaquita
la source
la source
sqrt(number)
lieu denumber
, et vous pouvez gagner un peu plus de temps - mais il y a beaucoup plus d'idées pour optimiser la recherche de nombres premiers.NSDate
objets et mesurer la différence entre eux.Réponses:
Voici une fonction Swift que j'ai écrite pour mesurer les problèmes de Project Euler dans Swift
Depuis Swift 3, il existe désormais une version de Grand Central Dispatch qui est "swiftified". La bonne réponse est donc probablement d'utiliser l' API DispatchTime .
Ma fonction ressemblerait à quelque chose comme:
Ancienne réponse
Pour Swift 1 et 2, ma fonction utilise NSDate:
Notez que l'utilisation de NSdate pour les fonctions de chronométrage est déconseillée: " L'heure système peut diminuer en raison de la synchronisation avec des références de temps externes ou en raison d'un changement d'utilisateur explicite de l'horloge. ".
la source
Date
côté, et bien sûr, cela rapporte 41,87 secondes. Je ne sais pas ce queuptimeNanoseconds
cela fait, mais cela ne rapporte pas la durée correcte.Ceci est une classe de minuterie pratique basée sur
CoreFoundation
sCFAbsoluteTime
:Vous pouvez l'utiliser comme ceci:
la source
mach_absolute_time
qui ne souffre pas de ce problème, alors je me demande pourquoi celui-ci n'est pas largement connu. Peut-être simplement parce que ce n'est pas bien documenté.Utilisez
clock
,ProcessInfo.systemUptime
ouDispatchTime
pour un démarrage simple.Pour autant que je sache, il existe au moins dix façons de mesurer le temps écoulé:
Basé sur l'horloge monotone:
ProcessInfo.systemUptime
.mach_absolute_time
avecmach_timebase_info
comme mentionné dans cette réponse .clock()
au standard POSIX .times()
au standard POSIX . (Trop compliqué car nous devons considérer le temps utilisateur par rapport au temps système, et les processus enfants sont impliqués.)DispatchTime
(un wrapper autour de l'API Mach time) comme mentionné par JeremyP dans la réponse acceptée.CACurrentMediaTime()
.Horloge murale basée:
(ne les utilisez jamais pour les métriques: voyez ci-dessous pourquoi)
NSDate
/Date
comme mentionné par d'autres.CFAbsoluteTime
comme mentionné par d'autres.DispatchWallTime
.gettimeofday()
au standard POSIX .Les options 1, 2 et 3 sont développées ci-dessous.
Option 1: API Process Info dans Foundation
où
diff:NSTimeInterval
est le temps écoulé en secondes.Option 2: API Mach C
où
diff:Double
est le temps écoulé en nano-secondes.Option 3: API d'horloge POSIX
où
diff:Double
est le temps écoulé en secondes.Pourquoi pas le temps de l'horloge murale pour le temps écoulé?
Dans la documentation de
CFAbsoluteTimeGetCurrent
:La raison est similaire à
currentTimeMillis
vsnanoTime
en Java :Ici
CFAbsoluteTime
fournit l'heure de l'horloge murale au lieu de l'heure de démarrage.NSDate
est également l'heure de l'horloge murale.la source
clock()
fonctions.ProcessInfo.processInfo.systemUptime
,mach_absolute_time()
,DispatchTime.now()
etCACurrentMediaTime()
. Mais la solution avecclock()
ne se convertissait pas correctement en secondes. Je vous conseille donc de mettre à jour votre première phrase comme suit : " Utilisez ProcessInfo.systemUptime ou DispatchTime pour une heure de démarrage précise. "Réponse la plus courte de Swift 4:
Il vous imprimera quelque chose comme 1.02107906341553 secondes écoulées (le temps variera bien sûr en fonction de la tâche, je vous montre simplement cela pour que vous puissiez voir le niveau de précision décimal pour cette mesure).
J'espère que cela aidera quelqu'un dans Swift 4 à partir de maintenant!
Mettre à jour
Si vous voulez avoir un moyen générique de tester des parties de code, je vous suggère l'extrait suivant:
la source
la source
Copiez et collez simplement cette fonction. Écrit en swift 5. Copie de JeremyP ici.
Utilisez-le comme
la source
Vous pouvez créer une
time
fonction pour mesurer vos appels. Je suis inspiré par la réponse de Klaas .Cette fonction vous permettrait de l'appeler comme ceci,
time (isPrime(7))
ce qui renverrait un tuple contenant le résultat et une chaîne de description du temps écoulé.Si vous ne souhaitez que le temps écoulé, vous pouvez le faire
time (isPrime(7)).duration
la source
Fonction d'aide simple pour mesurer le temps d'exécution avec fermeture.
Usage:
Résultat:
#Init - execution took 1.00104497105349 seconds
la source
vous pouvez mesurer les nanosecondes comme par exemple ceci:
la source
NSCalendar
procédure coûteuse, mais vous pouvez le faire avant de commencer à exécuter votre procédure, donc elle ne sera pas ajoutée à l'exécution de votre longue procédure ... gardez à l'esprit que l'appel de la création d'uneNSDate
instance et de la–components(_:, fromDate:)
méthode d' appel prend encore du temps, donc probablement vous n'obtiendrez jamais des0.0
nanosecondes.6.9
microsecondes sur mon appareil.J'utilise ceci:
Je ne sais pas si c'est plus ou moins précis que précédemment publié. Mais les secondes ont beaucoup de décimales et semblent capturer de petits changements de code dans des algorithmes comme QuickSort en utilisant swap () par rapport à l'implémentation de swap vous-même, etc.
N'oubliez pas d'augmenter vos optimisations de build lorsque vous testez les performances:
la source
Voici mon essai pour la réponse la plus simple:
Remarques
startTime
etendTime
sont du typeTimeInterval
, qui est juste untypealias
pourDouble
, il est donc facile de le convertir en unInt
ou autre. Le temps est mesuré en secondes avec une précision inférieure à la milliseconde.DateInterval
, qui inclut une heure de début et de fin réelle.la source
J'ai emprunté l'idée à Klaas de créer une structure légère pour mesurer le temps d'exécution et d'intervalle:
Utilisation du code:
La fonction d'arrêt n'a pas besoin d'être appelée, car la fonction d'impression donnera le temps écoulé. Il peut être appelé à plusieurs reprises pour obtenir le temps écoulé. Mais pour arrêter le chronomètre à un certain point de l'utilisation du code,
timer.stop()
il peut également être utilisé pour renvoyer le temps en secondes: Unelet seconds = timer.stop()
fois le chronomètre arrêté, le chronomètre d'intervalle ne le sera pas, de sorte que leprint("Running: \(timer) ")
donnera l'heure correcte même après quelques lignes de code.Voici le code pour RunningTimer. Il est testé pour Swift 2.1:
la source
Enveloppez-le dans un bloc de complétion pour une utilisation facile.
la source
C'est l'extrait que j'ai trouvé et il semble fonctionner pour moi sur mon Macbook avec Swift 4.
Jamais testé sur d'autres systèmes, mais j'ai pensé que cela valait la peine d'être partagé de toute façon.
Voici un exemple de son utilisation:
Une autre façon est de le faire plus explicitement:
la source
C'est comme ça que je l'ai écrit.
Pour mesurer un algorithme, utilisez- le comme ça.
la source
Classe Swift3 statique pour la synchronisation des fonctions de base. Il gardera une trace de chaque minuterie par nom. Appelez-le comme ceci au moment où vous souhaitez commencer à mesurer:
Appelez ceci pour capturer et imprimer le temps écoulé:
Voici la sortie: *** PhotoCapture ms écoulé: 1402.415125 Il existe un paramètre "useNanos" si vous souhaitez utiliser nanos. N'hésitez pas à changer au besoin.
}
la source
mach_timebase_info
est déjà mieux implémenté que vous ne l'avez fait dans le code source deProcessInfo.processInfo.systemUptime
. Alors faites simplementwatches[name] = ProcessInfo.processInfo.systemUptime
. Et* TimeInterval(NSEC_PER_MSEC)
si vous voulez des nanos.Basé sur la réponse de Franklin Yu et les commentaires de Cœur
Détails
Solution 1
mesure(_:)
Solution 2
Utilisation de la solution 2
la source
Date
pour mesurer quoi que ce soit est extrêmement déconseillé (maissystemUptime
ouclock()
sont OK). Quant aux tests, nous l'avonsmeasure(_:)
déjà fait.