ALTERNATIVE À LA FUNCTION VBA OU VB REPLACE (JUSQU'À 10 FOIS PLUS VITE, SANS AP

Signaler
Messages postés
291
Date d'inscription
vendredi 21 février 2003
Statut
Membre
Dernière intervention
13 mars 2015
-
Messages postés
12
Date d'inscription
jeudi 27 décembre 2007
Statut
Membre
Dernière intervention
21 janvier 2013
-
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/51268-alternative-a-la-function-vba-ou-vb-replace-jusqu-a-10-fois-plus-vite-sans-api

Messages postés
12
Date d'inscription
jeudi 27 décembre 2007
Statut
Membre
Dernière intervention
21 janvier 2013

L'instruction :
ReDim Preserve alHits(0 To lSize) As Long
prend environ 40 % du temps d'exécution. Pourquoi ne pas calculer la taille de ce tableau au préalable et n'effectuer le dimensionnement qu'une seule fois. Cela oblige à dupliquer quelques instructions mais s'avère payant. J'arrive à un rapport de 300 ms pour 16000 ms sur le même exemple.
Toujours impressionné par le travail de passionnés anonymes.
Messages postés
2065
Date d'inscription
lundi 11 avril 2005
Statut
Membre
Dernière intervention
14 mars 2016
8
Ouais, ben, si il y avait que ça... CompMode vaut quoi ? Le typage de Textin, SeachStr, Replacement sont variant... et pis, aucune optimisation... Toutes les options de Replace ne sont pas présente. Sans compter le genre de truc qui sert à rien : If IsNull(Replacement) Then Replacement = ""... Utiliser IsMissing, ou mieux une valeur par défaut nulle dans les paramètres... etc.

J'ai testé (enfin, si on peut dire) cette proposition, et, j'ai arrêté tout sauvagement VB6, faute de patience...

=

Sinon, le code de VICOSTA est optimisable déjà en utilisant les mêmes types d'optimisation que dans StrRapelace... Entre autre : utiliser LenB, InstrB...

Amicalement,
Us.
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
Pointer As Long
Messages postés
1
Date d'inscription
jeudi 31 décembre 2009
Statut
Membre
Dernière intervention
15 février 2010

Ou alors, il y a aussi :

Function ReplaceStr(TextIn, SearchStr, Replacement)
If IsNull(SearchStr) Or SearchStr = "" Then
ReplaceStr = TextIn
Exit Function
End If
On Error GoTo 0
If IsNull(Replacement) Then Replacement = ""
Dim WorkText As String, Pointer As Double
If IsNull(TextIn) Then
ReplaceStr = Null
Else
WorkText = TextIn
Pointer = InStr(1, WorkText, SearchStr)
Do While Pointer > 0
WorkText = left(WorkText, Pointer - 1) & Replacement & Mid(WorkText, Pointer + Len(SearchStr))
Pointer = InStr(Pointer + Len(Replacement), WorkText, SearchStr, CompMode)
Loop
ReplaceStr = WorkText
End If
End Function
Messages postés
178
Date d'inscription
lundi 5 juin 2006
Statut
Membre
Dernière intervention
30 novembre 2011

@ Brunnews: très bien vu, je pense que sur C+ ça va encore plus vite, dommage que je suis presque trop vieux pour m'y mettre.

@ US_30: merci pour le lien, j'ai testé, StrReplace ça va deux fois plus vite que VBReplace, et 20 fois plus vite que la function standard Replace
Messages postés
2065
Date d'inscription
lundi 11 avril 2005
Statut
Membre
Dernière intervention
14 mars 2016
8
Donc malgré tout, c'est bien l'optimisation de performance qui est recherché...

Comme j'ai trouvé l'équivalent plus rapide sur VBFrance, voici l'adresse :
http://www.vbfrance.com/codes/OPERATIONS-SUR-CHAINES-CARACTERE-OPTIMISEES-ETENDUES_49069.aspx

En reprenant les tests, la fonction StrReplace est encore 2 fois plus rapide que celle proposée ici.

Amicalement,
Us.
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
C'est déjà un peu plus clair.
mémoire addictionnelle = alloc mémoire (ici HeapAlloc).

1er algo:
1 seule alloc et affectation des octets.

2eme algo:
JUSQUE 500000: BEGIN
- alloc(LEN + 1);
- recopie de LEN octets;
- affectation du dernier octet;
- désalloc (HeapFree) de l'ancien bloc;
END

C'était pas pour pinailler mais les mots sont très importants.
S'ils permettent de mieux expliquer, ils nous aident surtout à mieux structurer et donc résoudre parfaitement un problème.

Si tu veux voir ce qui se passe en interne (sans VM):
REMPLACE DANS TOUTE UNE CHAINE
http://www.cppfrance.com/code.aspx?id=23920
Messages postés
178
Date d'inscription
lundi 5 juin 2006
Statut
Membre
Dernière intervention
30 novembre 2011

Ctd qu'à chaque manipulation de chainnes dont sa longueur se modifie considérablement, vb fait appel à une réserve de mémoire addictionnelle, ou à une liberation de cette mémoire comme c'est logique.
Parfois cet emplacement de mémoire est même déplacé par manque de place continue ce que fait augmenter encore d'avantage le temps de traitement sur la chainne. C'est pour ça que VB est lent, alors on doit appliquer les astuces.

Voici deux exemples qui provoquent le même résultat, plus ou moins vite:

Avec réservation de mémoire: Temps= 125 ms
C Space(500000): For I 1 To 500000: Mid$(C, I, 1) = Chr(I Mod 255): Next

Sans réservation de mémoire: Temps= 92626 ms !!!!!!
For I 1 To 500000: C C & Chr(I Mod 255): Next

Désolé je ne peux pas être plus simple

Dans la pratique ça peut se simplifier comme ça:
Exemple1: for i=1 to 500000: a = a & chr(i mod 255):next
Messages postés
21042
Date d'inscription
jeudi 23 janvier 2003
Statut
Modérateur
Dernière intervention
21 août 2019
20
"...ne reserve de la mémoire addctionnel pour travailler confortablement sans trop embarasser le système d'exploitation.".

En terme simple et surtout informatiquement, ça donne quoi ?
Messages postés
178
Date d'inscription
lundi 5 juin 2006
Statut
Membre
Dernière intervention
30 novembre 2011

Pas besoin de tester les autres codes sur vbfrance, j'ai consulté une bonne dizainne parmi le plus récents et aucun, tel que VB, ne reserve de la mémoire addctionnel pour travailler confortablement sans trop embarasser le système d'exploitation.
Messages postés
2065
Date d'inscription
lundi 11 avril 2005
Statut
Membre
Dernière intervention
14 mars 2016
8
Il y a un certain nombre de code sur REPLACE sur VBF... (et j'en parle pas sur internet). As-tu fait le test du plus rapide au moins ? Simple curiosité...

Amicalement,
Us.
Messages postés
178
Date d'inscription
lundi 5 juin 2006
Statut
Membre
Dernière intervention
30 novembre 2011

Sur mon poste et avec l'exemple de code que tu décris, ça va plus de 10 fois plus vite.
Bien sûr que, si le project ne comporte pas beaucoup de remplacements à éffectuer, cette function sera superflue.
Messages postés
291
Date d'inscription
vendredi 21 février 2003
Statut
Membre
Dernière intervention
13 mars 2015

Si effectivement dans certains contextes cette fonction s'avère plus rapide dans d'autres elle l'est moins, et au finale je ne suis pas convaincu car la plus part du temps il suffit de revoir algorithmie principale notamment la construction des boucles.

Un test avec
c = Replace(c, "co", "mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm", 1, , 1)
c = Replace(c, "mm", "ttttttttttttttttttttttttttttttttttttttttttttt", 1, , 1)
c = Replace(c, "tt", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", 1, , 1)
c = Replace(c, "bb", "zzzzzzZZZzzzzzzzzzzzzzzzzzzZZZZZZzzzz", 1, , 1)
c = Replace(c, "zz", "oooooooooooooooooooooooooooo", 1, , 1)
c = Replace(c, "zzzzz", "visual basic", 1, , 1)

S'avère presque équivalent sur mon poste.

Cependant très bonne source pour les version antérieures de VB et VBA qui n'implémente pas cette fonction.
JJDAI