Si je veux évaluer les performances temporelles de quelques algos en utilisant Date () ou Dispatch () , comment puis-je créer une fonction qui fait cela?
Pour exemple cet algo de recherche binaire. Comment puis-je le passer en tant que paramètre de fermeture et demander à la fermeture de mesurer tout le temps les performances en utilisant l'une des méthodes de chronométrage Swift ci-dessous? Veuillez répondre avec un exemple de fermeture. Merci.
let startingPoint = Date ()
laissez startingPoint = Dispatch (). now
func binarySearchForValue(searchValue: Int, array: [Int]) -> Bool {
var leftIndex = 0
var rightIndex = array.count - 1
while leftIndex <= rightIndex {
let middleIndex = (leftIndex + rightIndex) / 2
let middleValue = array[middleIndex]
if middleValue == searchValue {
return true
}
if searchValue < middleValue {
rightIndex = middleIndex - 1
}
if searchValue > middleValue {
leftIndex = middleIndex + 1
}
}
return false
}
3 Réponses :
Je ne sais pas exactement ce que vous recherchez ici et cette solution ci-dessous ne s'adaptera qu'à une seule signature de fonction spécifique pour tester
testBench(search: 3, array: [6,7,5,3]) {binarySearchForValue(searchValue: $0, array: $1)}
appelée ainsi
func testBench(search: Int, array: [Int], testCase test: (Int, [Int]) -> Bool) {
let start = DispatchTime.now()
test(search, array)
let end = DispatchTime.now()
print("\(start) - \(end)")
}
Cela marche. Il ne correspond qu'à une fonction spécifique, j'ai donc marqué la solution d'erreur comme correcte car elle utilise des génériques et est un guichet unique. De plus, le temps est calculé au lieu d'une expression. Je vais toujours voter pour votre réponse car elle fonctionne comme annoncé. Merci beaucoup.
Puisque vous voudrez peut-être mesurer différentes fonctions, il est probablement logique de capturer les arguments de la fonction dans la fermeture au lieu d'inclure leurs types dans la signature. Mais j'ai utilisé un type générique pour la valeur de retour. J'espère que c'est ce que vous recherchez:
let result = measure("search") { binarySearchForValue(searchValue: 3, array: [1, 3, 8]) }
print(result) // that's the result of the function that was measured, not the measurement
measure("some function") { functionWithoutReturnValue() }
Voici comment vous l'utilisez:
func measure<R>(_ label: String, operation: () -> R) -> R {
let start = DispatchTime.now()
let result = operation()
let end = DispatchTime.now()
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
let timeInterval = Double(nanoTime) / 1_000_000_000
print(String(format: "%@: %.9f s", label, timeInterval))
return result
}
Si la fonction n'a pas de valeur de retour , R sera () , donc cela devrait fonctionner aussi. N'assignez simplement le résultat à rien (voir l'exemple ci-dessus). Si vous voulez faire quelque chose avec la mesure autre que l'imprimer sur la console, vous pouvez le faire aussi. Mais vous ne l'avez pas précisé dans votre question, j'ai donc choisi print.
Oui, tu as raison. Si j'utilise un tri à bulles, par exemple, j'obtiens un avertissement La constante 'timeResult' déduit d'avoir le type '()', ce qui peut être inattendu et le résultat est () comme vous avez dit. Mais j'ai toujours la mesure du temps. J'ai ajouté une étiquette comme celle-ci func measure C'est ce que vous dites? Pourriez-vous s'il vous plaît ajouter le libellé à votre réponse? Je la marquerai comme la bonne réponse car votre fonction est plus polyvalente.
J'ai ajouté le paramètre label pour montrer ce que je voulais dire. J'ai également clarifié comment vous l'utilisez pour les fonctions qui n'ont pas de valeur de retour: n'assignez simplement le résultat à rien.
Merci pour la modification. p.s. J'ai juste mangé du gâteau et de la glace :)
Vous devriez utiliser XCTest pour mesurer les performances ... Il vous donne des statistiques appropriées pour votre méthode en termes de performances
i.e.
func testMyCodesPerformance() {
measureBlock {
someClass.doSomethingFancy()
}
}
Vous pouvez faire beaucoup plus en utilisant XCTest measureBlock pour les tests de performances
Wow. J'ai vraiment besoin de pratiquer le TDD. C'est tellement dur à cuire. J'aimerais pouvoir marquer deux bonnes réponses. Je vois que vous avez utilisé someClass . Pouvons-nous simplement passer des fonctions / algos à tester ou devons-nous d'abord créer une classe contenant toutes les fonctions / algos? Et si j'utilise des algos dans une aire de jeux sans cours?
Vous pouvez ... simplement importer XCTest
medium.com/square- coin-blog /…
J'ai réécrit ma question. Si vous pouviez supprimer votre commentaire, ce serait génial. Merci.
Ma solution privilégiée pour évaluer quelque chose de très rapidement et facilement consiste à créer un test unitaire, puis à utiliser
mesure. Notez que vous souhaiterez peut-être répéter cette opération suffisamment de fois pour que le temps de mesure soit observable et significatif.Vous continuez à utiliser le mot fermeture. Cela ne veut pas dire ce que vous semblez penser. L'intention de votre question n'est donc pas claire.
Ok donc j'ai changé le titre pour dire fonction au lieu de fermeture. Cependant, je ne pense pas que mon code soit, comme vous le dites, "dénué de sens". Il y a déjà deux bonnes réponses. D'une manière ou d'une autre, ils ont compris exactement ce que je voulais dire.