#1 Le 26/04/2020, à 14:40
- Hizoka
Temps d'execution d'une fonction / même code hors fonction
Bonjour à vous,
j'ai besoin d'améliorer le temps d’exécution d'un script sur lequel je bosse, chaque dixième de seconde est bon à prendre.
En faisant des tests, je me suis rendu compte de la chose suivante : le temps d'appel à une fonction interne alourdi beaucoup le temps de travail ?!
Je venais donc vers vous pour avoir vos avis, est-ce normal ?
Au final faut il se passer de fonction et allonger le code ?!
Quelles sont les bonnes pratiques lors de la création de fonction ?
Exemple très proche de mes besoins :
Le but est d'éliminer les %[0-9]/[0-9] et %[0-9] où chaque nombre peut être constitué entre 1 et 3 chiffres.
L'ordre est important car il ne faudrait pas dégager %1/1 avant %1/10 car sinon ce dernier se changera en 0.
PS : Si vous avez une façon plus rapide de réaliser cette action, je prends
Donc exit les sed & co ou les =~.
Version la plus rapide : 0m0,264s
time for x in {0..1000}
do
Value="%1 Bonjour %2/5 Monsieur"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
a="${Value}"
Value="%1/5 Bonjour %2 Monsieur"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
b="${Value}"
Value="%5/1 Bonjour %5 Monsieur"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
c="${Value}"
done
Visuellement c'est lourd, ça rallonge la taille du fichier...
Version avec une pseudo fonction, pratiquement aussi rapide : 0m0,312s
function ColorCleaning
{
Value="${1}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
}
time for x in {0..1000}
do
ColorCleaning "%1 Bonjour %2/5 Monsieur"
a="${Value}"
ColorCleaning "%1/5 Bonjour %2 Monsieur"
b="${Value}"
ColorCleaning "%5/1 Bonjour %5 Monsieur"
c="${Value}"
done
Je n'aime pas trop, je n'ai pas l'impression que c'est une "vraie fonction" (elle ne renvoie rien) et pas fan du côté toutes les variables sont globales et se mélangent entre le script et la fonction.
Mais c'est moins de lignes et plus lisible.
La même chose avec ce que je considère comme une vrai fonction : 0m9,696s :
function ColorCleaning
{
# Valeur à nettoyer
local Value="${1}"
# Nettoyage des couleurs possibles
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
# Renvoie du résultat
echo "${Value}"
}
time for x in {0..1000}
do
a=$(ColorCleaning "%1 Bonjour %2/5 Monsieur")
b=$(ColorCleaning "%1/5 Bonjour %2 Monsieur")
c=$(ColorCleaning "%5/1 Bonjour %5 Monsieur")
done
Visuellement agréable, la fonction renvoie une valeur récupérée, mais niveau timing, c'est juste pas possible.
Merci à vous, bon dimanche et bon courage pour le confinement.
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#2 Le 26/04/2020, à 15:33
- Watael
Re : Temps d'execution d'une fonction / même code hors fonction
j'aurais fait un tableau et une boucle :
for motif in "${arMotifs[@]}"; do [[ $Value == $motif* ]] && Value="${Value//$motif}"; done
Le tableau est défini au début du script, et plus de fonction.
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#3 Le 26/04/2020, à 15:46
- kamaris
Re : Temps d'execution d'une fonction / même code hors fonction
À mon avis, tu peux laisser bash faire tous ces tests en interne, pour obtenir des performances similaires à ton premier cas de test, mais en beaucoup plus léger et lisible :
shopt -s extglob
time for x in {0..1000}
do
Value="%1 Bonjour %2/5 Monsieur"
a=${Value//%+([0-9])?(\/)*([0-9])}
Value="%1/5 Bonjour %2 Monsieur"
b=${Value//%+([0-9])?(\/)*([0-9])}
Value="%5/1 Bonjour %5 Monsieur"
c=${Value//%+([0-9])?(\/)*([0-9])}
done
Hors ligne
#4 Le 26/04/2020, à 15:52
- Hizoka
Re : Temps d'execution d'une fonction / même code hors fonction
@Watael
En effet, pourtant je fais des trucs équivalents, j'aurais pu y penser
C'est pratiquement aussi rapide que les 1eres propositions : 0m0,403s
arMotifs=("%[0-9][0-9][0-9]/[0-9][0-9][0-9]" "%[0-9][0-9][0-9]/[0-9][0-9]" "%[0-9][0-9][0-9]/[0-9]" "%[0-9][0-9]/[0-9][0-9][0-9]" "%[0-9][0-9]/[0-9][0-9]" "%[0-9][0-9]/[0-9]" "%[0-9]/[0-9][0-9][0-9]" "%[0-9]/[0-9][0-9]" "%[0-9]/[0-9]" "%[0-9][0-9][0-9]" "%[0-9][0-9]" "%[0-9]")
time for x in {0..1000}
do
a="%1 Bonjour %2/5 Monsieur"
for motif in "${arMotifs[@]}"
do
[[ ${a} == *${motif}* ]] && a="${a//${motif}}"
done
b="%1/5 Bonjour %2 Monsieur"
for motif in "${arMotifs[@]}"
do
[[ ${b} == *${motif}* ]] && b="${b//${motif}}"
done
c="%5/1 Bonjour %5 Monsieur"
for motif in "${arMotifs[@]}"
do
[[ ${c} == *${motif}* ]] && c="${c//${motif}}"
done
done
C'est assez propre aussi.
@kamaris
Je pense jamais à shopt...
Pour le coup, il faut au moins 0.5sec, donc un chouille plus long
Mais niveau lisibilité, c'est top !
Après, mes questions de base vis à vis des fonctions restent d'actualité
Si y a des bonnes pratiques, des conseils...
De ce que je comprends de vos retours, c'est qu'il faut se passer des fonctions si possible XD
Merci
Dernière modification par Hizoka (Le 26/04/2020, à 16:02)
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#5 Le 26/04/2020, à 16:01
- kamaris
Re : Temps d'execution d'une fonction / même code hors fonction
J'ai fait une petite erreur en fait, en #3.
Pour être équivalent à tes tests plus haut, il faut faire
${Value//%+([0-9])?(\/+([0-9]))}
Du coup, c'est plus simple à tester, et j'ai des résultats un peu plus rapide qu'avec ton premier cas de test.
Ce qui serait rassurant : à tests logiquement équivalents, bash s'en sort mieux en interne qu'avec une suite de tests passés de l'extérieur.
Hors ligne
#6 Le 26/04/2020, à 16:11
- kamaris
Re : Temps d'execution d'une fonction / même code hors fonction
Pour les appels de fonctions, ça n'est jamais gratuit, mais ce qui coûte cher dans ton troisième cas de test, c'est la substitution de commande (un peu comme dans ce précédent sujet : ./viewtopic.php?id=2051383).
Car si tu fais
time for x in {0..1000}
do
ColorCleaning "%1 Bonjour %2/5 Monsieur" >/dev/null
ColorCleaning "%1/5 Bonjour %2 Monsieur" >/dev/null
ColorCleaning "%5/1 Bonjour %5 Monsieur" >/dev/null
done
tu retombes sur les mêmes ordres de grandeur.
Hors ligne
#7 Le 26/04/2020, à 16:11
- Watael
Re : Temps d'execution d'une fonction / même code hors fonction
grosso modo :
uneFonctionCorrecte()
{
local argumentFonction modification
argumentFonction=$1
modification=">$argumentFonction<"
echo "$modification"
}
argumentScript=$1
argumentScript=$(uneFonctionCorrecte "$argumentScript")
echo "$argumentScript"
Connected \o/
Welcome to sHell. · eval is evil.
Hors ligne
#8 Le 26/04/2020, à 16:17
- Hizoka
Re : Temps d'execution d'une fonction / même code hors fonction
Oui j'avais bien remarqué que c'était le même cas mais je me suis dis que j'étais peut être passé à côté d'un truc...
Ce que je pige pas, c'est pourquoi l'attribution des valeurs aux variables prend autant de temps...
et j'aime bien les fonctions, c'est facile à maintenir
@Watael
Oui, c'est à ça que ressemble mes fonctions.
Mais pour le coup :
argumentScript=$(uneFonctionCorrecte "$argumentScript")
Ça prend beaucoup de temps...
@karamis
J'aime ta proposition qui est classe mais si on complique la phrase, ouille...
0m15,651s
time for x in {0..1000}
do
Value="%1In %10opulentae %100domus %1/1quod %1/10indulta %1/100quorum %10/1extorres %10/10puniti %10/100converso %100/1indulta."
a=${Value//%+([0-9])?(\/+([0-9]))}
done
0m0,294s
time for x in {0..1000}
do
Value="%1In %10opulentae %100domus %1/1quod %1/10indulta %1/100quorum %10/1extorres %10/10puniti %10/100converso %100/1indulta."
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]/[0-9]* ]] && Value="${Value//%[0-9][0-9]\/[0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9][0-9]* ]] && Value="${Value//%[0-9]\/[0-9][0-9]}"
[[ ${Value} == *%[0-9]/[0-9]* ]] && Value="${Value//%[0-9]\/[0-9]}"
[[ ${Value} == *%[0-9][0-9][0-9]* ]] && Value="${Value//%[0-9][0-9][0-9]}"
[[ ${Value} == *%[0-9][0-9]* ]] && Value="${Value//%[0-9][0-9]}"
[[ ${Value} == *%[0-9]* ]] && Value="${Value//%[0-9]}"
a="${Value}"
done
0m0,322s
arMotifs=("%[0-9][0-9][0-9]/[0-9][0-9][0-9]" "%[0-9][0-9][0-9]/[0-9][0-9]" "%[0-9][0-9][0-9]/[0-9]" "%[0-9][0-9]/[0-9][0-9][0-9]" "%[0-9][0-9]/[0-9][0-9]" "%[0-9][0-9]/[0-9]" "%[0-9]/[0-9][0-9][0-9]" "%[0-9]/[0-9][0-9]" "%[0-9]/[0-9]" "%[0-9][0-9][0-9]" "%[0-9][0-9]" "%[0-9]")
time for x in {0..1000}
do
a="%1In %10opulentae %100domus %1/1quod %1/10indulta %1/100quorum %10/1extorres %10/10puniti %10/100converso %100/1indulta."
for motif in "${arMotifs[@]}"
do
[[ ${a} == *${motif}* ]] && a="${a//${motif}}"
done
done
Merci à vous pour vos retours et votre aide toujours aussi précieuse et de qualité
Dernière modification par Hizoka (Le 26/04/2020, à 16:24)
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#9 Le 26/04/2020, à 16:22
- kamaris
Re : Temps d'execution d'une fonction / même code hors fonction
Ah oui, ça c'est vrai que ça peut vite arriver, tu as raison :
Complicated extended pattern matching against long strings is slow, especially when the patterns contain alternations and the strings contain multiple matches. Using separate matches against shorter strings, or using arrays of strings instead of a single long string, may be faster.
Donc la proposition de Watael.
Hors ligne
#10 Le 26/04/2020, à 16:40
- kamaris
Re : Temps d'execution d'une fonction / même code hors fonction
Ou bien découper la chaine (je ne m'avoue pas vaincu ) :
shopt -s extglob
time for x in {0..1000}
do
Value="%1In %10opulentae %100domus %1/1quod %1/10indulta %1/100quorum %10/1extorres %10/10puniti %10/100converso %100/1indulta."
a=''
for p in $Value; do a+="${p//%+([0-9])?(\/+([0-9]))} "; done
a=${a:0:-1}
done
Hors ligne
#11 Le 26/04/2020, à 16:49
- Hizoka
Re : Temps d'execution d'une fonction / même code hors fonction
Pas mal pas mal en effet
Mais on s'éloigne de la simplicité
Mais c'est toujours très sympa de lire ce genre de code.
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne
#12 Le 29/04/2020, à 14:04
- LeoMajor
Re : Temps d'execution d'une fonction / même code hors fonction
bonjour,
autant compiler le regex si il est répété n fois; donc exit le shell, et la bienvenue aux langages qui savent le faire (python, ruby, java, c#, gambas, ...)
#!/usr/bin/python3.5
# -*- coding: utf-8 -*-
import re, time
deb = time.time()
l=[]
Value="%1In %10opulentae %100domus %1/1quod %1/10indulta %1/100quorum %10/1extorres %10/10puniti %10/100converso %100/1indulta."
pat=re.compile('%[0-9]+[/0-9]*')
for item in list(range(0,1000)):
res=pat.sub("",Value)
l.append(res)
#print(item,res)
print(l[1],len(l))
fin=time.time()
print("durée:",fin - deb)
In opulentae domus quod indulta quorum extorres puniti converso indulta. 1000
durée: 0.016808032989501953
Hors ligne
#13 Le 29/04/2020, à 14:21
- Sciensous
Re : Temps d'execution d'une fonction / même code hors fonction
grillé: j'allais proposer -> pour être rapide, faire du C
Dernière modification par Sciensous (Le 29/04/2020, à 14:22)
antiX 19 et 21 et Ubuntu 20.04 et 22.04
( sous LXDE et gnome-shell )
Hors ligne
#14 Le 29/04/2020, à 15:26
- Hizoka
Re : Temps d'execution d'une fonction / même code hors fonction
En effet, c'est rapide mais ça ne correspond aux autres tests.
La boucle est là pour simuler n appels au script, la regex sera exécutée à chaque lancement.
J'adore python mais pour le coup, là c'est un script bash
KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github
Hors ligne