Benchmark des extensions Swift vs méthodes: Swift 4.1 (mai 2018)

Les graphiques interactifs sont disponibles ici: http://minikin.me/extensions

‍ Motivation

Il y a quelques semaines, j'ai eu une discussion avec un programmeur iOS aux convictions profondes. L’un d’eux ressemble à ceci: «L’utilisation d’extensions Swift est une très mauvaise pratique en raison de l’augmentation spectaculaire des durées de compilation, ainsi que de sa lisibilité et de la clarté du code». Je ne vais pas juger de la lisibilité et de la clarté. Ce sont des préférences de style personnel, mais j’étais assez confus avec l’argument concernant le temps de compilation. Je me souviens qu'il y a eu des discussions sur le sujet il y a trois ans ou plus. Selon moi, trois ans pour Swift, 50 ans pour l’humanité. J'étais à peu près sûr que la situation n'était pas aussi grave que le pense cette personne, car je sais que l'équipe de Swift améliore continuellement le langage, y compris le temps de compilation. Je ne suis pas une telle personne qui va discuter sans avoir de solides arguments.

benchmarking

Le week-end dernier, j'avais quelques heures libres pour vérifier sa déclaration. J'ai écrit un script ruby ​​pour vérifier les performances des extensions par rapport aux méthodes. L’approche que j’ai choisie est assez simple, probablement même naïve, mais j’aimerais quand même voir des résultats. J'ai vérifié les cas suivants:

  • Classe + Méthodes
  • Classe + Extensions
  • Struct + Méthodes
  • Struct + Extensions

Le script Ruby crée n fonctions numériques pour chaque cas (dans l'exemple n = 3):

Classe + Méthodes

classe MyClass {
    Soit n = 1000
    func méthode_1 () {
      pour l'élément dans 0 .. 

Classe + Extensions

classe MyClass {
    soit n = 1000
    func méthode_1 () {
      pour l'élément dans 0 .. 

Je souhaitais également connaître la réponse à la question: combien d'extensions existent dans les applications Swift du monde réel? J'ai vérifié les applications open source les plus populaires écrites en Swift et quelques applications que nous avons développées dans notre société pour les clients pour un certain nombre d'extensions.

Pour exécuter des tests, définissez USE_EXTENSIONS sur true ou false dans Rakefile.

Exécuter des tests:

rake benchmark

Résultats des tests de nettoyage:

râteau propre

Résultats

Quand il s’agissait de représenter les données recueillies de manière claire et significative, mes compétences en science des données étaient très utiles. J'ai créé un script python main.py qui génère des graphiques de bokeh.

Les graphiques interactifs sont disponibles ici: http://minikin.me/extensions

Environnement de test: macOS 10.13.4, Swift 4.1, 2016 MacBook Pro, Intel Core i7 à 2,6 GHz, 16 Go LPDDR3 à 2133 MHz

Conclusions

En moyenne, l’approche méthodes utilise entre -6% et 70% de la vitesse de l’implémentation équivalente avec extensions.

Mais cela signifie-t-il que nous ne devrions pas utiliser les extensions? Probablement pas.
Dans les applications réelles, le nombre d'extensions atteint rarement 1 000. Si c'est le cas, la différence est d'environ 20%.

Bien sûr, dans une application réelle, nous obtiendrons des résultats différents, mais mesurés en différence de temps absolu, il est peu probable que les économies réalisées soient appréciables dans la plupart des circonstances.

Si vous voulez expérimenter, vous pouvez vérifier le dépôt sur GitHub.

Si vous avez des questions, n'hésitez pas à me contacter: @minikin

Mise à jour 1 (03.06.2018):

Yarik Arsenkin m'a demandé d'ajouter un point de repère pour le cas Classe + Fonctions privées dans Extension vs Classe + Méthodes privées. Veuillez vérifier les tableaux et les résultats mis à jour.