32 votes

Prévention des régressions de performances dans R

Qu'est-ce qu'un bon workflow pour détecter les régressions de performances dans les packages R? Idéalement, je recherche quelque chose qui s'intègre à R CMD check qui m'alerte lorsque j'ai introduit une régression de performance significative dans mon code.

Qu'est-ce qu'un bon workflow en général? Quelles autres langues fournissent de bons outils? Est-ce quelque chose qui peut être construit sur des tests unitaires supérieurs, ou qui est généralement fait séparément?

17voto

Iterator Points 10485

C'est très difficile question, et que je suis souvent confronté, comme je l'ai échanger un code différent dans un package pour accélérer les choses. Parfois, une régression de la performance s'accompagne d'un changement dans les algorithmes ou de la mise en œuvre, mais il peut également survenir en raison de changements dans les structures de données utilisées.

Qu'est ce qu'un bon flux de travail pour la détection de la performance des régressions dans les packages R?

Dans mon cas, j'ai tendance à avoir très spécifique des cas d'utilisation que je suis en train de prendre de la vitesse, avec fixes différents ensembles de données. Comme Spacedman écrit, il est important d'avoir un système informatique, mais c'est presque impossible: parfois, un ordinateur partagé, peut avoir d'autres processus que ralentir les choses de 10 à 20%, même quand il semble tout à fait inactif.

Mes étapes:

  1. Normaliser la plate-forme (par exemple une ou quelques machines, une machine virtuelle particulière, ou à une machine virtuelle + spécifiques de l'infrastructure, à la manière d'Amazon EC2 types d'instance).
  2. Normaliser l'ensemble de données qui sera utilisée pour accélérer les tests.
  3. Créer des scripts et intermédiaire fixe de sortie de données (c'est à dire enregistré .rdat fichiers) qui comportent très peu de transformations de données. Mon accent est mis sur une sorte de modélisation, plutôt que de la manipulation de données ou de transformation. Cela signifie que je veux donner exactement le même bloc de données à la modélisation de fonctions. Si, toutefois, la transformation de données est le but, alors assurez-vous que le pré-transformés/manipuler des données est aussi proche que possible de la norme à travers des tests des différentes versions du paquet. (Voir à cette question pour des exemples de memoization, cacher, etc., qui peut être utilisé pour normaliser ou de la vitesse non-focale calculs. Il fait référence à plusieurs paquets par les OP.)
  4. Répéter les tests plusieurs fois.
  5. À l'échelle les résultats relatifs à la fixe des repères, par exemple, le temps d'effectuer une régression linéaire, pour trier une matrice, etc. Cela peut permettre de "local" ou des variations transitoires dans les infrastructures, comme cela peut être dû à I/O, le système de mémoire, les paquets dépendants, etc.
  6. Examiner l'établissement de profils de sortie aussi énergiquement que possible (voir à cette question pour des idées, aussi de référencement sur les outils de l'OP).

    Idéalement, je suis à la recherche de quelque chose qui s'intègre avec R CMD vérifier que les alertes moi quand j'ai introduit une régression de la performance dans mon code.

    Malheureusement, je n'ai pas de réponse à cette question.

    Qu'est ce qu'un bon flux de travail en général?

    Pour moi, c'est assez similaire à la dynamique générale de code de test: est-ce que la sortie (temps d'exécution, dans ce cas) de la reproductibilité optimale et transparente? La transparence vient de comprendre ce qui influe sur l'ensemble du temps. C'est là que Mike Dunlavey les suggestions sont importants, mais je préfère aller plus loin, avec une ligne de profiler.

    Concernant une ligne de profils, voir ma précédente question, qui se réfère à des options en Python et Matlab pour d'autres exemples. Il est plus important d'examiner le temps de l'horloge, mais aussi très important de faire le suivi de l'allocation de mémoire, le nombre de fois que la ligne est exécutée, et la pile des appels en profondeur.

    Quelles sont les autres langues de fournir de bons outils?

    Presque toutes les autres langues ont de meilleurs outils. :) Les langages comme Python et Matlab ont la bonne et probablement familier des exemples d'outils qui peuvent être adaptés à cet effet. Bien que l'analyse de la dynamique est très important, l'analyse statique peut aider à identifier où il peut y avoir des problèmes plus sérieux. Matlab est un excellent analyseur statique qui peut rapporter lorsque les objets (par exemple, vecteurs, matrices) se développent à l'intérieur des boucles, par exemple. Il est terrible de trouver ce que via l'analyse dynamique - vous avez déjà perdu du temps d'exécution de découvrir quelque chose de ce genre, et il n'est pas toujours perceptible si l'exécution de votre contexte est assez simple (par exemple, juste quelques itérations, ou de petits objets).

    Dans la langue-agnostique méthodes, vous pouvez consulter:

    1. Valgrind & cachegrind
    2. La surveillance des e/S de disque, sale tampons, etc.
    3. La surveillance de la RAM (Cachegrind est utile, mais vous pourriez tout simplement surveiller l'allocation de RAM, et beaucoup de détails sur l'utilisation de la RAM)
    4. L'utilisation de plusieurs cœurs

    Est-il quelque chose qui peut être construit sur les tests unitaires, ou qui est généralement effectué séparément?

    C'est difficile de répondre. Pour l'analyse statique, il peut se produire avant que l'unité de test. Pour une analyse dynamique, on peut vouloir ajouter plus de tests. Il pense que séquentielle de conception (c'est à dire à partir d'un modèle expérimental cadre): si les coûts d'exécution semblent être, dans un certain nombre de statistiques des allocations pour la modification, la même, alors pas de tests supplémentaires sont nécessaires. Si, toutefois, la méthode B semble avoir un moyen d'exécution coût de plus que la méthode A, ensuite, il faut effectuer plus de tests intensifs.


Mise à jour 1: Si j'ai peut-être si audacieux, il y a une autre question que je voudrais recommander l'inclusion, qui est: "Quels sont certains des pièges de comparer le temps d'exécution de deux versions d'un paquet?" Ceci est analogue à l'hypothèse que les deux programmes qui mettent en œuvre le même algorithme doit avoir les mêmes objets intermédiaires. Ce n'est pas exactement vrai (voir cette question - non pas que je suis la promotion de mes propres questions, ici c'est juste travailler dur pour faire les choses mieux et plus vite...conduisant à de multiples DONC des questions sur ce sujet :)). De manière similaire, les deux exécutions du même code peuvent différer dans le temps consommé en raison de facteurs autres que la mise en œuvre.

Ainsi, certains pièges qui peuvent se produire, soit dans la même langue ou dans d'autres langues, au sein de la même instance d'exécution ou de l'autre côté "à l'identique" des instances, ce qui peut affecter l'exécution:

  1. Collecte des ordures ménagères - les différentes implémentations de la ou des langues peut frapper la collecte des ordures dans des circonstances différentes. Cela peut faire deux exécutions semblent différents, mais il peut être très dépendante du contexte, des paramètres, des ensembles de données, etc. Le GC-obsessionnelle exécution look plus lent.
  2. Nouvelle mise en mémoire cache au niveau du disque, de la carte mère (ex: L1, L2, L3 caches), ou à d'autres niveaux (par exemple, memoization). Souvent, la première exécution de payer une pénalité.
  3. Dynamic voltage scaling - Ce le suce. Quand il ya un problème, cela peut être l'un des plus difficiles bestioles à trouver, car il peut s'en aller rapidement. Il ressemble à cacher, mais il ne l'est pas.
  4. Tout emploi la priorité manager que vous ne connaissez pas.
  5. Une méthode utilise plusieurs cœurs ou ne astucieux des choses à propos de la façon dont le travail est morcelé entre les carottes ou les Processeurs. Par exemple, l'obtention d'un processus verrouillé à un noyau qui peut être utile dans certains scénarios. Une exécution d'un package R peut être plus de chance à cet égard, un autre paquet peut être très intelligent...
  6. Les variables, l'excès de transfert de données, sale caches, unflushed tampons, ... la liste est longue.

Le principal résultat est: dans l'idéal, comment doit-on tester les différences dans les valeurs attendues, sous réserve du caractère aléatoire créé par ordonnance effets? Bien, assez simple: revenir à la conception expérimentale. :)

Lorsque l'empirique des différences dans les temps d'exécution sont différentes de la "attendus" des différences, c'est génial d'avoir activé le système supplémentaire et de l'exécution de la surveillance, de sorte que nous n'avons pas à ré-exécuter les expériences jusqu'à ce que nous sommes en bleu dans le visage.

10voto

Dirk Eddelbuettel Points 134700

La seule façon de faire quelque chose ici est de faire des hypothèses. Supposons donc à l'identique de la machine, ou bien exigent un "recalibrage'.

Utilisez ensuite un test unitaire comme cadre, et traiter doit être fait dans les X unités de temps " comme une juste encore un autre test critère à remplir. En d'autres termes, faire quelque chose comme

 stopifnot( timingOf( someExpression ) < savedValue plus fudge)

donc, nous avons d'associer avant timings avec les expressions. L'égalité de tests de comparaisons à partir de l'une des trois tests unitaires paquets peuvent aussi être utilisés.

Rien que Hadley ne supportais pas donc je pense que l'on peut presque s'attendre à un nouveau package timr après le prochain long académique pause :). Bien sûr, cela doit être soit optionnel car sur un "inconnu" de la machine (pensez: CRAN tester le package) nous n'avons pas de point de référence, ou encore le facteur "aller à l'11" pour accepter automatiquement sur une nouvelle machine.

4voto

Brian Diggs Points 22433

Un récent changement annoncé sur la R-devel bétail pourrait donner une mesure brute pour cela.

Les CHANGEMENTS DANS la R-devel UTILITAIRES

‘R CMD check "peut éventuellement rapport timings sur les différentes parties du case: cela est contrôlé par des variables d'environnement documentés dans l'Écriture des Extensions de R'.

Voir http://developer.r-project.org/blosxom.cgi/R-devel/2011/12/13#n2011-12-13

L'ensemble du temps passé à exécuter les tests peuvent être vérifiés et comparés aux valeurs précédentes. Bien sûr, l'ajout de nouveaux tests augmentera le temps, mais spectaculaire de la performance des régressions pourrait encore être vu, mais manuellement.

Ce n'est pas aussi fine que le calendrier de soutien individuelles à l'intérieur des suites de test, mais elle ne dépend pas d'une suite de tests.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X