Existe-t-il des astuces d'optimisation standard pour Objective-C pour une exécution plus rapide selon les méthodes habituelles de "inlining" comme en C++ ou la balise "g ++ -fast"? Editer: Quelqu'un at-il un petit exemple utilisant SEL et IMP quand theMethod a deux (ou plus) entiers pour l'entrée?Optimisation Objective-C
Répondre
Voici une petite optimisation qui ne vaut pas vraiment le temps d'être mise en œuvre, et que je n'utilise jamais personnellement, mais je suppose que c'est toujours bon à savoir. Plutôt que d'envoyer à plusieurs reprises le même message au même objet, vous pouvez contourner l'envoi répété de méthodes en utilisant directement l'implémentation de la méthode. Par exemple, au lieu de:
for (int i = 0; i < 100000000; i++)
[someObject messageWithInt:i];
Vous pouvez essayer:
SEL theSelector = @selector(messageWithInt:);
IMP theMethod = [someObject methodForSelector:theSelector];
for (int i = 0; i < 100000000; i++)
theMethod (someObject, theSelector, i);
Cela signifie que la recherche de méthode est effectuée qu'une seule fois et vous pouvez appeler la méthode directement par la valeur retournée IMP
. Toutes les implémentations de méthode Objective-C prennent au moins deux arguments, le premier argument est l'objet récepteur de type id
, qui devient self
dans l'implémentation de la méthode, et le second argument est le sélecteur [de type SEL
] qui a été utilisé pour déterminer la méthode implémentation, et devient _cmd
dans l'implémentation de la méthode.
Cette approche peut rapidement se dégrader si vous n'utilisez pas la bonne définition de fonction “ ” (je ne me souviens pas du terme approprié). IMP
est un typedef
pour une fonction qui renvoie void*
et prend (id,SEL,...)
comme arguments. Cela peut rendre difficile à utiliser si la méthode renvoie effectivement quelque chose d'autre comme float
. Pour vous aider à ce sujet, vous pouvez lancer la valeur de retour de -methodForSelector:
, comme ceci:
typedef float (*MyMethodIMP)(id,SEL,int);
SEL theSel = @selector(messageWithInt:);
MyMethodIMP theMethod = (MyMethodIMP)[someObject methodForSelector:theSel];
float result = 0.0;
for (int i = 0; i < 100000000; i++)
result += theMethod (someObject, theSel, i);
Avec certains soins, vous pouvez enregistrer le theMethod
et vous pourrez peut-être utiliser pour toutes les instances d'une classe particulière, pas seulement un exemple, mais marchez prudemment.
Comme avec la plupart des éléments de performance, vous devez exécuter Instruments sur votre code pour voir où se trouvent les goulots d'étranglement. Les articles ci-dessus sont super ... si vous en avez besoin. Si vous ne le faites pas, cela rend le code difficile à lire. – nall
@nall: Absolument. J'ai fait quelques benchmarks de base, et dans des boucles serrées comme ci-dessus, le contournement de l'expédition a entraîné environ la moitié du temps d'exécution ('theMethod' a fait quelques calculs de base). Si vous passez beaucoup de temps dans 'objc_msgSend' (ou quelle que soit la méthode appelée de nos jours), alors contournement de dispatch peut être une option, sinon, comme vous le dites, ce sera plus une obfuscation qu'une optimisation. – dreamlax
C'est une optimisation vraiment intéressante, mais ne serait-il pas plus facile de simplement faire une fonction C au lieu d'obtenir l'IMP d'une méthode? – shosti
L'optimisation est mieux gérée par le compilateur. Les Mac utilisent GCC, donc l'indicateur GCC d'optimisation standard (-0 niveau) devrait fonctionner. Dans XCode, vous pouvez définir le niveau d'optimisation dans project settings. Si vous n'utilisez pas GCC, consultez la documentation du compilateur pour savoir comment activer l'optimisation.
Mise à jour: XCode 4 utilise le backend LLVM par défaut. Les interfaces GCC et clang utilisent les indicateurs d'optimisation "-O n". Pour GCC, n est un nombre entier compris entre 0 et 3, ou "s" ou (Apple uniquement) "z". Pour clang, n est un nombre entier de 0 à 4, ou "s".
C'est vrai - hors de la mémoire c'est réglé sur [-O3] – SK9
Un grand merci à tous pour vos suggestions et votre temps! Si vous le souhaitez, pouvez-vous donner un court exemple en utilisant SEL et IMP lorsque theMethod prend deux (ou plus) entiers comme entrée. – SK9
@SpecialK: un petit exemple de * quoi *? Vouliez-vous faire un commentaire sur la réponse de dreamlax? – outis
- 1. Combine chaîne en ObjectiveC
- 2. Analyseur AMF0 dans ObjectiveC
- 3. NSString question ObjectiveC
- 4. Reliure ObjectiveC classe C# problème
- 5. alloca et ObjectiveC Garbage Collector
- 6. Personnalisation de writeToFile dans ObjectiveC
- 7. Optimisation
- 8. Allocation de mémoire dynamique 2D - ObjectiveC
- 9. MVC utilisé dans la programmation ObjectiveC
- 10. Chargement d'une séquence d'images dans InterfaceBuilder -ObjectiveC
- 11. Optimisation SQL
- 12. Optimisation SQL
- 13. Optimisation css
- 14. MySQL Optimisation
- 15. Optimisation SQLite
- 16. Optimisation C++
- 17. Optimisation DATEDIFF
- 18. Aider avec le code GCC et ObjectiveC et Cygwin
- 19. Comment résoudre les fuites dans le code suivant? ObjectiveC
- 20. Puis-je placer un sélecteur ObjectiveC @ dans un NSDictionary?
- 21. optimisation des requêtes SQLite
- 22. GROUP BY Optimisation
- 23. dessin sur UITableViewCell Optimisation
- 24. optimisation MySQL existence record
- 25. Optimisation de HttpWebResponse - GetResponse
- 26. Optimisation d'une requête NHibernate
- 27. lighttpd optimisation fastcgi
- 28. optimisation des requêtes
- 29. mysql optimisation des requêtes
- 30. Sélectionnez Optimisation des requêtes
Ce sujet est discuté en détail ici: http://www.mulle-kybernetik.com/artikel/Optimization/ – codewarrior
Dans un cadre de haut niveau comme le cacao, les optimisations les plus petits comme celui-ci sont une perte de temps (autre que de changer les paramètres du compilateur), car beaucoup de classes fondamentales sont déjà fortement optimisées. Vous devriez seulement optimiser si le profilage montre que quelque chose prend beaucoup de temps supplémentaire. – shosti