PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 2024 → [27/10/2004] Le Saviez-Vous ?
[27/10/2004] Le Saviez-Vous ?
Débuté par Le Support Technique Gratuit, 27 oct. 2004 20:04 - 10 réponses
Posté le 27 octobre 2004 - 20:04
Bonjour,

Optimiser vos traitements en utilisant les constantes rangPremier, rangSuivant, rangPrécédent et rangDernier de la fonction ExtraitChaîne().

La commande ExtraitChaine possède de nouvelles constantes : rangPremier, rangSuivant, rangPrécédent et rangDernier. Utilisez ces constantes si la chaîne à explorer est longue. Dans ce cas la vitesse d'exécution est indépendante de la longueur de la chaîne, contrairement à la syntaxe utilisant un indice. L'optimisation peut aller de 1 à 100 sur des chaînes de taille importante ! ! !

---
Cordialement,
Le Support Technique Gratuit
Posté le 09 juillet 2015 - 14:42
Bonjour

J'ai développé des logiciels en client serveur avec énormément d'échanges de chaine don beaucoup d'extraitChaine.
J'essaye donc d'optimiser ce traitement et je constates des choses étranges. D'ou mes questions

1-Comment se comporte rangpremier , rangsuivant... lors de l'utilisation imbriqué de plusieurs extraitchaine? (ou pire sur plusieurs thread)


2- J'ai fais une nouvelle fonction (dans une classe) pour extraire une chaine
Procedure ExtraitSuivant()
IndiceDep est entier =:PosDepart+1
IndiceFin est entier
ChaineRetour est chaîne =""

IndiceFin=Position(:MaChaineTotale,:MonSeparateur,IndiceDep)
ChaineRetour=:MaChaineTotale[[IndiceDep A (IndiceFin-1)]]

:PosDepart=(IndiceFin+:TailleSep-1)

RENVOYER ChaineRetour


jusque la super j'arrive à diviser presque par 2 le temps de traitement mais surprise lors de l'imbrication!!!
Je m'explique:
POUR i=1 A NB
MaChaine1 est chaîne=EXTRAITCHAINE_TYPE_A(ChaineTotale)
POUR j=1 A NB2
MaChaine2 est chaîne=EXTRAITCHAINE_TYPE_B(MaChaine1)
FIN
FIN


Voila mes resultats:
EXTRAITCHAINE_TYPE_A== ExtraitChaine WLangage
EXTRAITCHAINE_TYPE_B== ExtraitChaine WLangage
Temps d'execution: 2200ms

EXTRAITCHAINE_TYPE_A== ExtraitChaine Niko
EXTRAITCHAINE_TYPE_B== ExtraitChaine Niko
Temps d'execution: 2600ms

(la vous allez me dire elle est pourri ta fonction...) mais...

EXTRAITCHAINE_TYPE_A== ExtraitChaine Niko
EXTRAITCHAINE_TYPE_B== ExtraitChaine WLangage
Temps d'execution: 770ms

EXTRAITCHAINE_TYPE_A== ExtraitChaine WLangage
EXTRAITCHAINE_TYPE_B== ExtraitChaine Niko
Temps d'execution: 4100ms


Comment se comporte les fonctions sur les chaines lors des appels imbriqué?
Quelqu'un à déjà constaté de telles différences de temps de traitement?

Merci d'avances pour vos réponses....
Posté le 11 juillet 2015 - 16:30
Essayez
pour i= 1 _A_ NB
.....
pour j=1 _A_ NB2
....

au lieu de
pour i=1 A NB
Membre enregistré
63 messages
Popularité : +4 (4 votes)
Posté le 15 juillet 2015 - 08:25
Merci beaucoup pour votre réponse mais cette modification de la boucle ne change pas le temps d'exécution....
Il s'agit bien d'un soucis sur la gestion de la chaine...
Membre enregistré
36 messages
Posté le 15 juillet 2015 - 17:10
Bonjour,

Pour répondre à votre question rangsuivant et consort permettent de mémoriser la position et donc de simplifier le code et l'exécution.

Vu ce que vous voulez faire je vous invite à utiliser l'instruction POUR TOUT pour vos parcours. C'est très rapide et vous pouvez les imbriquer.
Petite remarque : ne déclarer pas de variable dans une boucle (même si ça marche...)

Bon dev,

Olivier
Membre enregistré
63 messages
Popularité : +4 (4 votes)
Posté le 16 juillet 2015 - 10:55
Merci également....
C'a améliore légèrement mais ca n'explique pas les différences énormes de temps entres les traitements!
Je note pour la déclaration à l'intérieur des boucles...:merci:
Membre enregistré
36 messages
Posté le 16 juillet 2015 - 19:50
De rien.
J'ai plutôt de bonnes performances menée sur de grosses chaînes...

Après ça dépend de ce que vous faites exactement et de la chaîne en entrée.
Doc pour aller plus loin, il faudrait que vous postiez un code plus complet et un exemple de la chaîne.
Membre enregistré
63 messages
Popularité : +4 (4 votes)
Posté le 27 juillet 2015 - 09:30
Bonjour
Je relance le sujet avec mon code...

1: Une classe cExtraitChaineNiko avec dedans,

cExtraitChaineNiko est une Classe

PRIVÉ
MaChaineTotale est une chaîne
MonSeparateur est une chaîne
NBElement est entier
PosDepart est un entier
TailleTotale est un entier
TailleSep est un entier
FIN

Procedure ExtraitSuivant(ChaineRetour est une chaîne)
IndiceDep est entier =:PosDepart+1
IndiceFin est entier
IndiceFin=Position(:MaChaineTotale,:MonSeparateur,IndiceDep)
ChaineRetour=:MaChaineTotale[[IndiceDep A (IndiceFin-1)]]
:PosDepart=(IndiceFin+:TailleSep-1)

Procedure Init(pChaineTotale est une chaîne,pSeparateur est chaîne)
:MaChaineTotale=pChaineTotale
:MonSeparateur=pSeparateur
:PosDepart=0
:NBElement=ChaîneOccurrence(:MaChaineTotale,:MonSeparateur)
:TailleTotale=Taille(:MaChaineTotale)
:TailleSep=Taille(:MonSeparateur)
RENVOYER :NBElement


2: Une procédure locale qui utilise la fonction WL extrait chaine

Procedure ProcedureLocaleWL(MaChaine est chaîne)
SEPCOL est chaîne ="|"
CHtest est une chaîne

CHtest=ExtraitChaîne(MaChaine,1,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,2,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,3,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,4,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,5,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,6,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,7,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,8,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,9,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,10,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,11,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,12,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,13,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,14,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,15,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,16,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,17,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,18,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,19,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,20,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,21,SEPCOL,DepuisDébut)
CHtest=ExtraitChaîne(MaChaine,22,SEPCOL,DepuisDébut)


3: Une autre procédure locale qui utilise la fonction Niko extrait chaine

Procedure ProcedureLocaleNiko(MaChaine est chaîne)
SEPCOL est chaîne ="|"
CHtest est une chaîne

MonEC est cExtraitChaineNiko

MonEC:Init(MaChaine,SEPCOL)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)
MonEC:ExtraitSuivant(CHtest)



4: pour finir un code d'appel des différents cas dans un bouton

Nb est entier
i est un entier
DuréeMaFonction1 est un entier
Ch est une chaîne
MonEC est cExtraitChaineNiko
SEPCOL est chaîne="|"
SEPLIG est chaîne=RC

MaChaineTotale est chaîne =Répète("P02_MX202153|4|P02_MX202153|TEST|F_TEST|NIKOP|0|0|55|153|P02||10079487|1|20150723173319053|20150723173432356|||1002|20150723173319053|1|0|"+RC,1000)



ChronoDébut(2)
POUR z=1 _A_ 50
Nb=ChaîneOccurrence(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
Ch=ExtraitChaîne(MaChaineTotale,i,SEPLIG,DepuisDébut)
ProcedureLocaleWL(Ch)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement WL / WL a duré " + DuréeMaFonction1 + " millisecondes")


ChronoDébut(2)
POUR z=1 _A_ 50
Nb=ChaîneOccurrence(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
Ch=ExtraitChaîne(MaChaineTotale,i,SEPLIG,DepuisDébut)
ProcedureLocaleNiko(Ch)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement WL / Niko a duré " + DuréeMaFonction1 + " millisecondes")


ChronoDébut(2)
POUR z=1 _A_ 50
Nb=MonEC:Init(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
MonEC:ExtraitSuivant(Ch)
ProcedureLocaleWL(Ch)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement Niko / WL a duré " + DuréeMaFonction1 + " millisecondes")

ChronoDébut(2)
POUR z=1 _A_ 50
Nb=MonEC:Init(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
MonEC:ExtraitSuivant(Ch)
ProcedureLocaleNiko(Ch)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement Niko / Niko a duré " + DuréeMaFonction1 + " millisecondes")


Voila le résultat!!






Merci énormément à ceux qui prendront le temps de tester ce code....
Posté le 27 juillet 2015 - 12:01
Bonjour,

Finalement, vous ne testez pas la proposition du ST.

SousCh est une chaîne

ChronoDébut(2)
POUR z=1 A 50
Nb=ChaîneOccurrence(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
Ch=ExtraitChaîne(MaChaineTotale,i,SEPLIG,DepuisDébut)
POUR j = 1 _A_ ChaîneOccurrence(Ch,SEPCOL)
SousCh = ExtraitChaîne(Ch,j,SEPCOL, DepuisDébut)
FIN
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement [Syntaxe 1 - Extraction] a duré " + DuréeMaFonction1 + " millisecondes")

ChronoDébut(2)
Ch = ExtraitChaîne(MaChaineTotale,rangPremier,SEPLIG)
TANTQUE Ch <> EOT
SousCh = ExtraitChaîne(Ch, rangPremier, SEPCOL)
TANTQUE SousCh <> EOT
SousCh = ExtraitChaîne(Ch, rangSuivant, SEPCOL)
FIN
Ch = ExtraitChaîne(MaChaineTotale, rangSuivant, SEPLIG)
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement [Syntaxe 2 - Parcours] a duré " + DuréeMaFonction1 + " millisecondes")


Sur ma configuration et sous WD18,
Syntaxe 1 : 3182 ms
Syntaxe 2 : 13 ms

Je vous laisse le soin de reporter cela dans votre test pour disposer du comparatif global.

Hemgé
Membre enregistré
63 messages
Popularité : +4 (4 votes)
Posté le 28 juillet 2015 - 11:03
Bonjour

J'ai donc ajouté une autre procedure

Procedure ProcedureLocaleWLST(MaChaine est chaîne)
SEPCOL est chaîne ="|"
CHtest est une chaîne
CHtest = ExtraitChaîne(MaChaine, rangPremier, SEPCOL)
TANTQUE CHtest <> EOT
CHtest = ExtraitChaîne(MaChaine, rangSuivant, SEPCOL)
FIN


et 2 nouveaux type d'appel pour avoir le test complet

ChronoDébut(2)
POUR z=1 _A_ 50
Ch = ExtraitChaîne(MaChaineTotale,rangPremier,SEPLIG)
TANTQUE Ch <> EOT
ProcedureLocaleWLST(Ch)
Ch = ExtraitChaîne(MaChaineTotale, rangSuivant, SEPLIG)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement WLST / WLST a duré " + DuréeMaFonction1 + " millisecondes")

ChronoDébut(2)
POUR z=1 _A_ 50
Nb=MonEC:Init(MaChaineTotale,SEPLIG)
POUR i=1 _A_ Nb
MonEC:ExtraitSuivant(Ch)
ProcedureLocaleWLST(Ch)
FIN
FIN
DuréeMaFonction1=ChronoValeur(2)
Trace("Le traitement Niko / WLST a duré " + DuréeMaFonction1 + " millisecondes")


Resultats...







WLST / WLST est à peu près identique à Niko / WL (il manquait la boucle de 50 sur votre test). J'avais écarté rangsuivant et ses copains car je n'ai pas confiance lors de l'utilisation en multithread (ou et comment sont mémorisé les variables de parcours de la chaine?...)

Encore une fois merci d'avoir pris du temps pour répondre....
Posté le 28 juillet 2015 - 17:36
Bonjour,

Gros juron (ça on peut l'écrire en respectant l'étiquette) pour cet oubli de boucle.

J'ai évidemment repris le tout, avec les résultats suivants :
- syntaxe 1 : 3.214 ms
- syntaxe 2 : 675 ms
Soit une optimisation de 5.

Hemgé