Ce à quoi il faut faire gaffe pour les perf c’est la dimension sur laquelle tu itères: si ça fait des sauts en mémoire c’est moins bon que si les données sont lues à la suite. La dimension en question dépend des strides en effet. Pour un tableau créé de manière standard, il faut itérer sur la dernière dimension de préférence (mais en pratique t’as pas souvent le choix).
@Sam C’est vrai que parfois une API pour des tableaux à N dimensions ça serait pas du luxe. Mais bon dans mon cas j’ai souvent besoin d’algèbre linéaire, donc je ne réfléchis même pas à prendre autre chose que numpy.
]]>Réponse très instructive sur numpy. J’avais remarqué qu’il y avait quelques itérateurs dans numpy, mais je n’avais pas bien compris leur fonctionnement.
En revanche, il me semblait que pour bénéficier des performances de « vues sur les tableaux », il fallait vraiment se servir de « strides ». Si tu as des fonctions / macros de plus haut niveau, je suis preneur.
C’est une stratégie similaire à numpy, que j’ai vue dans RapidMiner.
Après, il y a moyen de rentrer carrément dans la sémantique des algorithmes, et de se demander si on peut trouver une version « incrémentale » de tous les algorithmes de base en algèbre linéaire.
Pour l’instant, à ce sujet j’ai trouvé une piste intéressante, où il existe une version « Monte-Carlo » de toutes les opérations algébriques de base en algèbre matricielle. Chaque opération devient la somme de résultats partiels et successifs issus de tirages statistiques.
C’est particulièrement adapté pour la notion de « q-bit » qui fonctionne un peu en mode « itérateur » :
– Une librairie Python pour du Monte-Carlo / qbits : « quameon »
– « Monte Carlo Linear Algebra » : http://www.mit.edu/~dimitrib/Monte_Carlo_Linear_Algebra.pdf
Voilà, voilà…
]]>C’est aussi pour ça que request est pas inclus dans python par exemple, alors qu’il y aurait un intérêt énorme.
Sinon pour l’itération sur les tableaux numpy on garde le côté lazy sur les tableaux à plusieurs dimensions: l’itération se fait sur la première dimension, et renvoit des vues sur le tableau initial avec les dimensions restantes, donc ça prend que dalle de mémoire. Mais de manière générale la philosophie est différente, et il sera bien plus efficace de vectoriser que d’itérer (quand c’est possible).
Jouer avec numpy.ndarray.strides c’est très bas level quand même, l’intérêt de numpy c’est justement de ne pas s’emmerder avec !
]]>>>> import sys
>>> range(sys.maxsize)
range(0, 9223372036854775807)
]]>Néanmoins, j’aurais des réserves à propos de ta remarque sur count
.
Par quel autre moyen simple peux-tu retourner un générateur qui renvoie sans s’arrêter une suite de nombres ? Range impose en effet un point d’arrêt, ce que ne fait pas count. Or parfois il peut être utile de ne pas mettre de limites dans une telle énumération (du moment qu’on sait ce qu’on fait bien entendu…), comme par exemple pour se dispenser d’un while
explicite ce qui parfois facilite la compréhension.
count
n’est donc pas entièrement à jeter :)
Super article. Le plus dur, pour moi, c’est de me dire “putain mais là je me suis fait chier à écrire un algo alors que j’avais dropwhile
qui aurait pu me le faire immédiatement” et de me dire ensuite “alors si je veux remplacer toutes les fois où j’ai mis un if not truc: continue
par un dropwhile
combien de temps ça va me prendre”…
Et euh sinon je viens de killer ma vm après avoir tenté le list(infinite_generator()). Ben oui, moi quand on me dit “ça va crasher” ben c’est plus fort que moi: faut que je teste… ;)
]]>s/mais vous il/mais il
]]>