Bonjour,
Ce sujet a pour but de regrouper les petites astuces permettant d'augmenter la vitesse d'exécution d'un code Python.
Exemple de chronomètre :
--Code PHP:
import time
import c4d
def chrono():
t = time.time()
for i in xrange(10000000) :
pass
print time.time() - t
if __name__=='__main__':
chrono()
Vérifier un booléen :
██████████ 0,70 sCode PHP:
if a is True :
Code PHP:
if a :
█████ 0,35 s - Gain de 50 %
--
Boucle :
██████████ 0,84 sCode PHP:
for i in range(10000000) :
███ 0,24 s - Gain de 71 %Code PHP:
for i in xrange(10000000) :
Je découvre des choses intéressantes, si quelqu'un a une explication, elle est la bienvenue :
Créer un vecteur :
██████████ 4,25 sCode PHP:
v = c4d.Vector(0, 0, 0)
█████████ 3,86 s - Gain de 10 %Code PHP:
v = c4d.Vector(0.0, 0.0, 0.0)
██████ 2,60 s - Gain de 39 %Code PHP:
v = c4d.Vector()
Il en va de même pour créer un vecteur quelconque ayant les trois mêmes valeurs, Vector(1.0) sera plus rapide que Vector(1.0, 1.0, 1.0) et Vector(1, 1, 1).
Ma théorie :
Dans le premier cas, j'imagine que Python doit convertir les entiers en flottants, ce qui rend le second cas plus rapide étant donné qu'on entre flottants directement, et le dernier cas n'a probablement pas à vérifier les valeurs entrées, d'où le gain.
Dernière modification par César Vonc ; 17/09/2012 à 17h58.
Salut,
Super sujet César.
Voilà un petit bout de code pour comparer le temps d'execution de 2 instructions :
Pour le c4d.Vector, je pense que tu as raison, la conversion implicite prend du temps. Cela se vérifie en comparant :Code PHP:
import timeit
import c4d
LOOP_COUNT = 10000000
def compare(stmt1, stmt2):
t1 = timeit.Timer(stmt1, "import c4d").timeit(number=LOOP_COUNT)
t2 = timeit.Timer(stmt2, "import c4d").timeit(number=LOOP_COUNT)
print "Statement 1 : %.3f s" % t1
print "Statement 2 : %.3f s" % t2
faster = 1 if t1 < t2 else 2
if faster == 2:
t1, t2 = t2, t1
diff = t2 - t1
percent = 100.0 - t1 / t2 * 100.0
print "-> Statement %d is %.3f s (%.1f %%) faster" % (faster, diff, percent)
test1 = """
a = 42
if a & 1:
pass
"""
test2 = """
a = 42
if a % 2:
pass
"""
def main():
compare(test1, test2)
plus rapide (~ 10 %) queCode PHP:
a = 1.0
a += 1.0
AussiCode PHP:
a = 1.0
a += 1
plus rapide (~ 14 %) queCode PHP:
a = b = c = x
et de ce fait "c4d.Vector(1)" sera quand même plus rapide que "c4d.Vector(1.0, 1.0, 1.0)" mais moins que "c4d.Vector(1.0)"Code PHP:
a, b, c = x, y, z
Attention certains exemples sont destinés à être utilisés uniquement dans le cas d'un problème de rapidité avéré.
Tester la nullité d'un entier :
██████████ 6,04 sCode PHP:
if a == 0 :
█████████ 5,38 s - Gain de 11 %Code PHP:
if not a :
--
Tester la positivité d'un index inférieur :
██████████ 0,80 sCode PHP:
if i - 1 > 0:
████████ 0,60 s - Gain de 25 %Code PHP:
if i > 1:
--
Insérer dans un tableau :
██████████ 1,44 sCode PHP:
tab = []
for i in xrange(5):
tab.append(i)
█████████ 1,22 s - Gain de 15 %Code PHP:
tab = []
append = tab.append
for i in xrange(5):
append(i)
--
Opérations sur les vecteurs :
██████████ 2,75 sCode PHP:
v = c4d.Vector(10, 20, 30)
w = c4d.Vector(1, 2, 3)
x = c4d.Vector(v.x * w.x, v.y * w.y, v.z * w.z)
y = c4d.Vector(v.x + w.x, v.y + w.y, v.z + w.z)
████ 0,99 s - Gain de 64 %Code PHP:
v = c4d.Vector(10, 20, 30)
w = c4d.Vector(1, 2, 3)
x = v ^ w
y = v + w
--
Tester si le tableau contient au moins 1 élément :
██████████ 1,52 sCode PHP:
a = []
if len(a) == 0:
█████ 0,76 s - Gain de 50 %Code PHP:
a = []
if not a:
Dernière modification par xs_yann ; 26/09/2012 à 17h37.
Excellent, Yann !
Dis donc, je connaissais pas cette formulation :
C'est plutôt curieux, append a quel type ?Code PHP:
tab = []
append = tab.append
for i in xrange(5):
append(i)
C'est le même principe que les pointeurs sur fonctions en C++.Envoyé par console python
Deux liens en anglais avec pleins de conseils :
http://wiki.python.org/moin/PythonSpeed/PerformanceTips
http://stackoverflow.com/questions/7...ng-python-code
Merci pour les liens.
Division de flottants :
██████████ 1,00 sCode PHP:
a = 5.0 / 2
████████ 0,80 s - Gain de 20 %Code PHP:
a = 5.0 / 2.0
████ 0,36 s - Gain de 64 %Code PHP:
a = 5.0 * 0.5
Préférer la multiplication plutôt que la division tant que possible.
Remplacer 1/3 par 0,333 est préférable si la précision n'est pas de mise.
Note : 5 / 2 renverra un nombre entier (2).
Dernière modification par César Vonc ; 29/09/2012 à 18h38.
Édit : finalement tout ça était faux, il faut mieux rester avec des vecteurs tout le temps car la conversion de vecteurs en tuples est beaucoup trop longue.
Dernière modification par César Vonc ; 27/01/2014 à 12h06.