Duniter / Ğ1
Wiki
Autres projets
Duniter / Ğ1
Wiki
Autres projets
This is an old revision of the document!
Il existe dans beaucoup de langages (C/C++, JS…) une structure switch (ou match en Rust). Mais pas en Python. Trouvons le moyen le plus optimisé de la remplacer.
Ici, nous allons traduire ce code en Python:
for(int i=0; i<n; i++) {
switch(i%4) {
case 0: v = random()+1; break;
case 1: v = random()+2; break;
case 2: v = random()+3; break;
default: v = random()+4;
}
}
Un tableau de comparaison des performances est disponible à la fin.
for i in range(n):
v = 0
if i%4 == 0:
v = random()+1
elif i%4 == 1:
v = random()+2
elif i%4 == 2:
v = random()+3
else:
v = random()+4
Voilà l'approche naïve et redondante.
for i in range(n):
v = {
0: random()+1,
1: random()+2,
2: random()+3
}.get(i, random()+4)
On utilise un dict et sa méthode get avec une valeur par défaut.
for i in range(n):
try:
v = {
0: random()+1,
1: random()+2,
2: random()+3
}[i]
except KeyError:
v = random()+4
Ce que beaucoup de gens disent sur les bonnes manières de programmer en Python, c'est qu'il est bon d'utiliser des try sans perdre le temps de vérifier les données. Or, cet exemple montre que ce n'est pas toujours vrai.
t = [0,1,2]
for i in range(n):
if i in t:
v = {
0: random()+1,
1: random()+2,
2: random()+3
}[i]
else:
v = random()+4
Alors on vérifie les données avant et on laisse tomber le try. Au cas où le in serait plus rapide avec une list qu'avec un dict, on essaie avec une list.
t = [0,1,2]
f = {
0: lambda: random()+1,
1: lambda: random()+2,
2: lambda: random()+3
}
for i in range(n):
if i in t:
v = f[i]()
else:
v = random()+4
Ne redéclarons pas notre dict à chaque itération grâce aux lambda.
f = {
0: lambda: random()+1,
1: lambda: random()+2,
2: lambda: random()+3
}
for i in range(n):
if i in f:
v = f[i]()
else:
v = random()+4
Et finalement on peut abandonner la list.
Les durées sont donnés en secondes pour n = 50,000,000.