Christophe a écrit :
pil91 a écrit :
(snip)
Je pensais améliorer les choses en remplacant la concaténation de ma
chaine un append dans un tableau, puis un join
(...)
Excès d'autosatisfaction, c'est quif quif, 18s, sur 1 000 000
d'enregistrement avec cette structure
Ah oui, à ce sujet l'implémentation CPython optimise automatiquement les longues suites de concaténations dans une même string de la façon dont tu le fais.
Plus ou moins... la version avec un assignement augmenté (s += xxx) est un poil plus rapide que celle avec un réassignement (s = s + xxx)
Un petit bench valant mieux qu'un long discours:
from timeit import Timer
repeat = xrange(100000)
def concat():
s = ''
for i in repeat:
s = s + 'aaaaa'
def concat_aug():
s = ''
for i in repeat:
s += 'aaaaa'
def append_join():
s = []
for i in repeat:
s.append('aaaaa')
s = ''.join(s)
def local_append_join():
s = []
append = s.append
for i in repeat:
append('aaaaa')
s = ''.join(s)
def comp_join():
s = ''.join('aaaaa' for i in repeat)
timers = [
(funcname, Timer('%s()' % funcname, 'from __main__ import %s' % funcname))
for funcname in ('concat', 'concat_aug', 'append_join', 'local_append_join', 'comp_join')
]
for funcname, t in timers:
print funcname, t.timeit(100)
Résultats ici (python 2.5.1 sous gentoo-linux):
concat 3.99100494385
concat_aug 3.96803593636
append_join 6.26043510437
local_append_join 3.67693090439
comp_join 3.72800898552
Le mauvais résultat de append_join par rapport à local_append_join s'explique par le hit dû au lookup de list.append, suivi de l'instanciation de l'objet méthode. Comme quoi cette simple optimisation (localiser les methodes appelées dans une boucle 'intensive') est très payante. Par contre, dans le cas de l'OP, je ne sais pas si ce sera vraiment plus intéressant (pour la boucle intérieure de do_import) dans la mesure où c'est, justement dans une boucle imbriquée. Mais bon, pil, tu peux tester les deux... AMHA, selon le jeu d'essai (données sources), tu aura des résultats en faveur tantôt de la solution local_append_join, tantôt en faveur de la solution comp_join.
Avec une version un peu plus ancienne de Python, tu aurais certainement vu une très grande amélioration.
Aucun doute....