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

jjDai Messages postés 291 Date d'inscription vendredi 21 février 2003 Statut Membre Dernière intervention 13 mars 2015 - 9 févr. 2010 à 20:46
cs_Norpac Messages postés 12 Date d'inscription jeudi 27 décembre 2007 Statut Membre Dernière intervention 21 janvier 2013 - 21 févr. 2010 à 11:34
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

cs_Norpac Messages postés 12 Date d'inscription jeudi 27 décembre 2007 Statut Membre Dernière intervention 21 janvier 2013
21 févr. 2010 à 11:34
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.
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
15 févr. 2010 à 13:33
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.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 févr. 2010 à 12:41
Pointer As Long
cs_bernan Messages postés 1 Date d'inscription jeudi 31 décembre 2009 Statut Membre Dernière intervention 15 février 2010
15 févr. 2010 à 10:21
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
vicosta Messages postés 178 Date d'inscription lundi 5 juin 2006 Statut Membre Dernière intervention 30 novembre 2011
12 févr. 2010 à 20:00
@ 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
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
12 févr. 2010 à 11:44
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.
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 févr. 2010 à 10:15
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
vicosta Messages postés 178 Date d'inscription lundi 5 juin 2006 Statut Membre Dernière intervention 30 novembre 2011
12 févr. 2010 à 01:56
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
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
11 févr. 2010 à 14:02
"...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 ?
vicosta Messages postés 178 Date d'inscription lundi 5 juin 2006 Statut Membre Dernière intervention 30 novembre 2011
11 févr. 2010 à 02:43
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.
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
10 févr. 2010 à 15:15
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.
vicosta Messages postés 178 Date d'inscription lundi 5 juin 2006 Statut Membre Dernière intervention 30 novembre 2011
9 févr. 2010 à 21:34
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.
jjDai Messages postés 291 Date d'inscription vendredi 21 février 2003 Statut Membre Dernière intervention 13 mars 2015
9 févr. 2010 à 20:46
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
Rejoignez-nous