Performance de NSKeyedArchiver
UniX
Membre
Salut.
J'utilise NSKeyedArchiver pour enregistrer sur le disque des données. Il s'agit d'un tableau contenant environs 1500 objets d'une classe perso.
Le temps d'enregistrement sur disque est très long (à peu près 30 secondes), alors que le fichier résultant sur le disque ne fait que 960 ko .....
J'ai monitoré pour voir quelle partie du processus était longue, en plaçant un NSLog dans la méthode encodeWithCoder: de la classe perso. Je pensais que ça pouvait venir du fait qu'il y a 1500 objets ....
Et bien non ! Je passe au travers de la méthode encodeWithCoder: en 1 ou 2 secondes.
Donc à priori, c'est vraiment la phase d'écriture sur disque qui est longue ....
Pourquoi ?
J'utilise NSKeyedArchiver pour enregistrer sur le disque des données. Il s'agit d'un tableau contenant environs 1500 objets d'une classe perso.
Le temps d'enregistrement sur disque est très long (à peu près 30 secondes), alors que le fichier résultant sur le disque ne fait que 960 ko .....
J'ai monitoré pour voir quelle partie du processus était longue, en plaçant un NSLog dans la méthode encodeWithCoder: de la classe perso. Je pensais que ça pouvait venir du fait qu'il y a 1500 objets ....
Et bien non ! Je passe au travers de la méthode encodeWithCoder: en 1 ou 2 secondes.
Donc à priori, c'est vraiment la phase d'écriture sur disque qui est longue ....
Pourquoi ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Utilise Shark pour ce genre de choses... Tu verras bien si c'est le I/O qui occupent le processeur ou autre chose.
1 - Tu lances ton application
2 - Tu lances Shark
3 - Tu sélectionnes "Process" à la place d'"Everything"
4 - Tu sélectionnes le processus de ton appli
5 - Tu sélectionnes "Time Profile" s'il n'est déjà selectionné
6 - Tu prépares bien la tâche que tu veux monitorer sur ton appli pour n'avoir plus qu'un bouton à appuyer par exemple
7, 8, 9 - T'appuies sur "Start" dans Shark, tu lances ta tâche dans ton appli et une fois fini, sur "Stop" dans Shark
10 - Il va analyser tout ce qui s'est passé et te sortir dans l'ordre ce qui a pris le plus de temps
L'exécution de Shark s'est terminé toute seule, sans que j'ai à cliquer sur Stop. Je sais pas si c'est normal ....
Voici les résultats que j'obtiens.
J'ai bien la méthode enregistrementTemporaireThread qui enregistre les données sur le disque.
Après, je sais pas trop quoi dire de plus ...
Donc, ce n'est pas dû à l'écriture sur le disque, mais bien à l'archivage de tes classes.
Ou plus haut : "finishEncoding"
C'est la construction de ta classe vers le NSData...
Là on ne voit même pas les I/O ; ton truc est tellement long que Shark n'a pas pu les enregistrer, ils n'avaient pas commencé (il enregistre 30s max je crois)
J'ai toute une série de
La seule chose, c'est que j'ai 47 variables d'instance. J'ai essayé de ne pas en encoder certaines, et je gagne des secondes. Mais théoriquement, j'en ai besoin de toutes .... (je dois pouvoir en supprimer quelques unes que je recalcule lors du décodage).
Je suis un peu dans l'impasse là il me semble ....
On dirait que ton programme cherche des données dans un Plist binaire ; tout tourne un peu autour de ça ("FindBuckets"...)
Dans SudokuX, j'ai aussi un paquet de choses à enregister, de gros tableaux 9*9*9, icônes, curseurs etc... et ça prend une fraction de secondes (avec Shark, ce qui apparaà®t consommateur, c'est la gestion de l'icône dans le Dock au moment de l'enregistrement ::) )
[Edit] J'y pense... Aurais-tu fait un projet Core-Data / XML ?
Si oui, apparemment ce n'est pas du tout adapté...
Pour te décrire ce que j'enregistre :
- le root object est un NSDictionary, qui contient des NSArray (3 ou 4)
- les NSArray contiennent des objets perso (3 ou 4) qui ont environs 10 variables d'instance (des NSString, booleen, .... rien d'extraordinaire).
- une des variables d'instance est un NSArray qui contient d'autres objets persos (les fameux avec 47 variables d'instance) et peuvent être plusieurs centaines.
A priori, ce qui prend du temps, c'est le traitement de ces derniers objets ....
Ca m'intéresse aussi cette affaire
-> "Double-Click for Symbol", doublie-cliquer dessus, et rentrer _CFBinaryPlistWriteToStream
J'ai testé en ne mettant pas le tiret devant _CFBinaryPlistWriteToStream, idem ...
"__CFBinaryPlistWriteToStream"
Plus mettre "CoreFoundation" dans "Location" (peut-être pas obligatoire ; il le trouvera peut-être tout seul)
Bien être en mode "Debug", et vérifier que dans la console qu'il y ait bien marqué :
Le problème c'est qu'il l'utilise aussi quand il lit les préférences, donc faut peut-être le placer après...
(ou alors mettre une condition de stack sur le breakpoint, mais je ne connais pas assez bien gdb pour faire ça)
Tout est clair.
Je viens de faire un essai avec juste les 1500 objets dans un NSArray, c'est aussi long. En revanche, si je rempli avec 1500 objets qui ont tous les mêmes valeurs de variables d'instance, là c'est rapide. Mais je suppose que c'est une optimisation de NSKeyedArchiver qui prévoit ce cas là ....