... moment de l’exécution de délégation et / ou de mémoire.
Si ce n’est pas vrai, prouvez-le avec un extrait de code. Remarque Cette accélération par vectorisation ne compte pas. L’accélération doit provenir de (
, `` ,...) lui-même.
... moment de l’exécution de délégation et / ou de mémoire.
Si ce n’est pas vrai, prouvez-le avec un extrait de code. Remarque Cette accélération par vectorisation ne compte pas. L’accélération doit provenir de (
, `` ,...) lui-même.
L' apply
fonctions dans R de ne pas fournir de meilleures performances que les autres en boucle fonctions (par exemple, for
). Une exception à cette règle est - lapply
qui peut être un peu plus rapide car il n'a plus de travail dans le code C que dans R (voir à cette question pour un exemple).
Mais en général, la règle est que vous devez utiliser une application de fonction pour plus de clarté, pas pour la performance.
Je voudrais ajouter à ce que s'appliquent les fonctions n'ont pas d'effets secondaires, ce qui est une distinction importante quand il s'agit de la programmation fonctionnelle avec R. Cela peut être substituée à l'aide d' assign
ou <<-
, mais qui peuvent être très dangereux. Effets secondaires aussi faire un programme plus difficile à comprendre parce qu'une variable d'état dépend de l'histoire.
Edit:
Juste pour souligner ce point avec un exemple trivial que de manière récursive qui calcule la suite de Fibonacci, ce qui pourrait être exécuté plusieurs fois afin d'obtenir une mesure exacte, mais le point est qu'aucune de ces méthodes sont très différentes de la performance:
> fibo <- function(n) {
+ if ( n < 2 ) n
+ else fibo(n-1) + fibo(n-2)
+ }
> system.time(for(i in 0:26) fibo(i))
user system elapsed
7.48 0.00 7.52
> system.time(sapply(0:26, fibo))
user system elapsed
7.50 0.00 7.54
> system.time(lapply(0:26, fibo))
user system elapsed
7.48 0.04 7.54
> library(plyr)
> system.time(ldply(0:26, fibo))
user system elapsed
7.52 0.00 7.58
Edit 2:
Concernant l'utilisation en parallèle des packages de R (par exemple, rpvm, l'ipmb, neige), elles ne fournissent généralement apply
les fonctions de la famille (même l' foreach
package est essentiellement équivalent, malgré le nom). Voici un exemple simple de l' sapply
fonction snow
:
library(snow)
cl <- makeSOCKcluster(c("localhost","localhost"))
parSapply(cl, 1:20, get("+"), 3)
Cet exemple utilise un socket cluster, pour lequel aucun logiciel supplémentaire ne doit être installé; sinon, vous aurez besoin de quelque chose comme PVM ou MPI (voir Tierney de clustering page). snow
a la suite d'appliquer les fonctions de:
parLapply(cl, x, fun, ...)
parSapply(cl, X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
parApply(cl, X, MARGIN, FUN, ...)
parRapply(cl, x, fun, ...)
parCapply(cl, x, fun, ...)
Il est logique qu' apply
fonctions doivent être utilisées pour l'exécution en parallèle car ils ont pas d' effets secondaires. Lorsque vous modifiez la valeur d'une variable à l'intérieur d'un for
de la boucle, il est défini globalement. D'autre part, tous apply
fonctions peuvent en toute sécurité être utilisés en parallèle parce que les changements sont locales à l'appel de la fonction (à moins que vous essayez d'utiliser assign
ou <<-
, dans ce cas, vous pouvez présenter des effets secondaires). Inutile de dire, il est essentiel d'être prudent quant à local vs global variables, surtout au moment de l'exécution en parallèle.
Edit:
Voici un exemple trivial pour démontrer la différence entre for
et *apply
jusqu'à présent que les effets secondaires sont concernés:
> df <- 1:10
> # *apply example
> lapply(2:3, function(i) df <- df * i)
> df
[1] 1 2 3 4 5 6 7 8 9 10
> # for loop example
> for(i in 2:3) df <- df * i
> df
[1] 6 12 18 24 30 36 42 48 54 60
Notez comment l' df
dans le parent de l'environnement est modifiée par l' for
mais pas *apply
.
Parfois l’accélération peut être substantielle, comme quand vous devez imbriquer les boucles for pour obtenir la moyenne basée sur un regroupement de plus d’un facteur. Ici vous avez deux approches qui vous donnent exactement le même résultat :
Les deux donnent exactement le même résultat, étant une matrice de 5 x 10 avec les moyennes et les lignes nommées et les colonnes. Mais :
Et voilà. Ce que je gagne ? ;-)
J'ai écrit ailleurs qu'un exemple comme Shane n'a pas vraiment de stress a la différence de performance entre les différents types de syntaxe de boucle parce que le temps est passé au sein de la fonction plutôt que de réellement soulignant la boucle. En outre, le code injustement compare une boucle for avec pas de mémoire avec la famille de fonctions qui retournent une valeur. Voici un exemple légèrement différent qui met l'accent sur le point.
foo <- function(x) {
x <- x+1
}
y <- numeric(1e6)
system.time({z <- numeric(1e6); for(i in y) z[i] <- foo(i)})
# user system elapsed
# 4.967 0.049 7.293
system.time(z <- sapply(y, foo))
# user system elapsed
# 5.256 0.134 7.965
system.time(z <- lapply(y, foo))
# user system elapsed
# 2.179 0.126 3.301
Si vous envisagez d'enregistrer le résultat d'appliquer ensuite les fonctions de la famille peut être BEAUCOUP plus de sucre syntaxique.
(le simple unlist de z n'est que de 0,2 s de sorte que le lapply est beaucoup plus rapide. L'initialisation de la z dans la boucle for est assez rapide parce que je suis en train de faire la moyenne des 5 dernières de 6 pistes jusqu'à se déplacer qu'à l'extérieur du système.le temps ne serait guère affecter des choses)
Lors de l’application de fonctions sur des sous-ensembles d’un vecteur, `` peut être un peu plus rapide qu’une boucle for. Exemple :
``, cependant, ne fournit pas une augmentation de la vitesse dans la plupart des cas, et dans certains cas, peut être même beaucoup plus lent :
Mais pour ces situations, nous avons colSums et rowSums :
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.