2009-07-20 8 views
2

Je suis devenu un grand fan de KVO/KVC. J'aime la façon dont mon architecture MVC reste propre. Cependant, je ne suis pas amoureuse de l'énorme performance que j'éprouve lorsque j'utilise KVO dans la boucle de rendu interne de l'application de rendu 3D que je conçois, où les messages se déclenchent 60 fois par seconde pour chaque objet observé - potentiellement des centaines.Cocoa Touch Programmation. KVO/KVC dans la boucle interne est super lent. Comment puis-je accélérer les choses?

Quels sont les trucs et astuces pour accélérer KVO? Spécifiquement, j'observe une valeur scalaire - pas un objet - alors peut-être que l'emballage/déballage me tue. Je suis également en train de mettre en place et d'arrêter l'observation

[foo addObserver:bar forKeyPath:@"fooKey" options:0 context:NULL]; 
[foo removeObserver:bar forKeyPath:@"fooKey"]; 

dans la boucle interne. Peut-être que je prends un coup pour ça. Je veux vraiment, vraiment, garder l'énorme flexibilité que KVO me procure. Y a-t-il de la vitesse qui peut donner un coup de main?

Cheers, Doug

+0

Comment savez-vous que le coup de performance est causé par KVO/KVC, avez-vous profilé? Je suis désolé si la réponse est un YES flagrant, mais parfois les gens prennent des hypothèses sur les goulets d'étranglement de la performance ... – zoul

+0

Je profil religieusement. Mon cœur s'est effondré lorsque la performance s'est évanouie en rampant avec KVO. Ungh. – dugla

Répondre

4

envoi de messages de Objective-C et d'autres caractéristiques sont à l'écoute et très rapide pour ce qu'ils fournissent, mais ils ne sont toujours approchent pas le potentiel de l'écoute C pour les tâches de calcul:

NSNumber *a = [NSNumber numberWithIntegerValue:(b.integerValue + c.integerValue)]; 

est façon plus lente que:

NSInteger a = b + c; 

et personne ne fait les mathématiques sur les objets en Objective-C pour cette raison (bien qu'une et la syntaxe est horrible). La puissance d'Objective-C est que vous avez un bon système d'objets basé sur un message expressif où vous pouvez jeter les bits chers et utiliser du C pur quand vous en avez besoin. Le KVO est l'un des éléments les plus coûteux. J'aime le KVO, je l'utilise tout le temps. Il est coûteux en calcul, surtout lorsque vous avez beaucoup d'objets observés. Une boucle interne est ce petit morceau de code que vous exécutez encore et encore, quoi que ce soit qui sera fait encore et encore. C'est l'endroit où vous devriez éliminer les fonctions de POO si besoin est, où vous ne devriez pas allouer de mémoire, où vous devriez envisager de remplacer les appels de méthode par des fonctions inline statiques. Même si vous réussissez à obtenir des performances acceptables dans votre boucle de rendu, les performances seront nettement inférieures à celles obtenues si vous obtenez une notification et une logique de répartition aussi coûteuses.

Si vous voulez vraiment essayer de le maintenir avec KVO voici quelques choses que vous pouvez essayer de faire les choses vont plus vite:

  1. Commutateur automatique à KVO manuel dans vos objets. Cela peut vous permettre de réduire les notifications parasites
  2. Agréger les mises à jour: Si vos valeurs intermédiaires sur un intervalle de temps ne sont pas pertinentes et que vous pouvez reporter pendant un certain temps (comme le cadre d'animation suivant) ne pas afficher le changement, que le changement doit être posté et attendre que la minuterie se déclenche, vous pourriez éviter un tas de mises à jour intermédiaires de courte durée. Vous pouvez également utiliser une sorte de proxy pour agréger les modifications liées entre plusieurs objets.
  3. Fusionner les propriétés observables: Si vous avez un grand nombre de propriétés dans un type d'objet qui pourrait changer, vous feriez mieux de faire observer une seule propriété "hasChanges" et de demander à l'observateur d'interroger les propriétés.
+0

Louis, Ma réticence à abandonner KVO a à voir avec le maintien d'une belle architecture MVC propre. J'observe le comportement qui se passe dans mon modèle. Voici un exemple typique: un tas de sprites zippant autour de l'écran que je voudrais associer des effets sonores à chacun à un niveau très granulaire. Je voudrais décharger des sons à une bibliothèque sonore complètement séparée avec la messagerie KVO reliant les deux. La pénalité de vitesse me forcera à tirer des sons dans le moteur de sprite qui est moins qu'idéal. – dugla

+0

Si vous voulez vraiment essayer de le faire fonctionner, il y a certaines choses que vous pouvez faire, et je les ai ajoutées à la publication, mais elles peuvent nuire un peu à la rupture entre le modèle et la vue. –

+0

Merci beaucoup pour l'aide Louis. À votre santé. – dugla

Questions connexes