Bonjour,
Suite à cette contribution, je m'interroge aujourd'hui sur la fonction Join.
En effet, celle-ci comporte des petits "manquements" :
- Elle ne traite que des Array de String,
- Elle ne traite que des Array à 1 dimension.
Traitons ces deux cas l'un après l'autre.
Test du passage, en paramètre de la fonction Join, d'un Array de type Long :
Il nous faut donc convertir cet Array en String, pour cela il existe plusieurs méthodes de conversion.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 Option Explicit Const MIN As Long = 5000 Const MAX As Long = 35000 Const SEP As String = " - " Sub DemoJoin() Dim i&, s$ ReDim v(MIN) As Long For i = LBound(v) To UBound(v) v(i) = i Next On Error Resume Next s = Join(v, SEP) If Err.Number > 0 Then MsgBox Err.Description On Error GoTo 0 End Sub
J'en connais personnellement 3, mais peut-être en auriez-vous une (ou plusieurs) autre(s) plus performante(s).
- Via une variable de type String intermédiaire :
Le principe :
On boucle sur notre Array (de type Long) et on stocke, à chaque boucle, son contenu dans une variable String.
Le code de démo :
Les résultats :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 Option Explicit Const MIN As Long = 5000 Const MAX As Long = 35000 Const SEP As String = " - " Sub TestViaString() Dim i&, j&, t#, s$ Debug.Print "Méthode du String intermédiaire : " For j = MIN To MAX Step MIN ReDim v(j) As Long s = vbNullString For i = LBound(v) To UBound(v) v(i) = i Next t = Timer For i = LBound(v) To UBound(v) s = s & v(i) & SEP Next s = Left(s, Len(s) - Len(SEP)) Debug.Print Right(s, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(s) Next End Sub
Conclusion :Méthode du String intermédiaire :
5000 ==> 0,046875 sec. Lenght : 33894
10000 ==> 0,201171875 sec. Lenght : 68895
15000 ==> 0,494140625 sec. Lenght : 108895
20000 ==> 0,9609375 sec. Lenght : 148895
25000 ==> 1,611328125 sec. Lenght : 188895
30000 ==> 2,595703125 sec. Lenght : 228895
35000 ==> 6,689453125 sec. Lenght : 268895
L'augmentation exponentielle de la durée d'exécution en fonction du nombre d'éléments à ajouter à notre variable String me fait conclure que cette manière de procéder n'est valable que sur de "petites" variables tableaux.
- La conversion en Array de String via CStr et utilisation de la fonction Join :
Le principe :
On passe les valeurs de notre Array de Long, dans un Array de String, en utilisant la fonction de conversion CStr.
Une fois cette conversion réalisée, on utilise Join.
Le code de démo :
Ayant déjà testé, j'ai augmenté délibérément les valeurs des constantes MIN (de 5 000 à 500 000) et MAX (de 35 000 à 3 500 000).
Les résultats :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 Option Explicit Const MIN As Long = 500000 Const MAX As Long = 3500000 Const SEP As String = " - " Sub TestConversionCStr() Dim i&, j&, t#, str$ Debug.Print "Méthode de conversion (CStr) : " For j = MIN To MAX Step MIN ReDim v(j) As Long str = vbNullString For i = LBound(v) To UBound(v) v(i) = i Next t = Timer ReDim s(j) As String For i = LBound(v) To UBound(v) s(i) = CStr(v(i)) Next str = Join(s, SEP) Debug.Print Right(str, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(str) Next End Sub
Conclusion :Méthode de conversion (CStr) :
500000 ==> 0,54296875 sec. Lenght : 4388896
1000000 ==> 1,3046875 sec. Lenght : 8888897
1500000 ==> 2,01953125 sec. Lenght : 13888897
2000000 ==> 2,751953125 sec. Lenght : 18888897
2500000 ==> 3,548828125 sec. Lenght : 23888897
3000000 ==> 4,26171875 sec. Lenght : 28888897
3500000 ==> 5,05078125 sec. Lenght : 33888897
On voit, en utilisant cette méthode, que l'augmentation de la durée d'exécution n'est plus exponentielle comme dans notre premier essai.
Les temps peuvent paraître long (plus de 5 secondes) mais il faut relativiser.
En effet, il n'est pas fréquent de croiser des Array de plus de trois millions d'éléments.
- La conversion en Array de String SANS CStr et avec utilisation de la fonction Join :
Le principe :
On passe les valeurs de notre Array de Long, dans un Array de String.
Une fois cette conversion réalisée, on utilise Join.
Le code de démo :
Les résultats :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 Option Explicit Const MIN As Long = 500000 Const MAX As Long = 3500000 Const SEP As String = " - " Sub TestViaArrayString() Dim i&, j&, t#, str$ Debug.Print "Méthode Array de String : " For j = MIN To MAX Step MIN ReDim v(j) As Long str = vbNullString For i = LBound(v) To UBound(v) v(i) = i Next t = Timer ReDim s(j) As String For i = LBound(v) To UBound(v) s(i) = v(i) Next str = Join(s, SEP) Debug.Print Right(str, Len(CStr(j))) & " ==> " & Timer - t & " sec. Lenght : " & Len(str) Next End Sub
Conclusion :Méthode Array de String :
500000 ==> 0,48828125 sec. Lenght : 4388896
1000000 ==> 1,1640625 sec. Lenght : 8888897
1500000 ==> 1,81640625 sec. Lenght : 13888897
2000000 ==> 2,62890625 sec. Lenght : 18888897
2500000 ==> 3,234375 sec. Lenght : 23888897
3000000 ==> 4,609375 sec. Lenght : 28888897
3500000 ==> 4,62109375 sec. Lenght : 33888897
Les résultats des deux dernières méthodes sont équivalents.
Cela m'amène à penser que l'une utilise l'autre en arrière-plan.
Dans quel sens, cela je ne sait pas, et ça ne revêt pas un grand intérêt pour le sujet.
Après cette mini étude, je pencherais pour la méthode de conversion avec CStr pour remédier au souci n° 1.
J'ai également testé avec des Array de Double et de Date.
Un "poil" plus lent, mais c'est entièrement normal, du aux "poids" différents de ces types de variable.
2 questions donc :
- Verriez-vous une autre méthode?
- Les tests présentés ici (y compris ceux avec Double et Date) sont-ils suffisants?
Merci déjà rien que pour la lecture de ce long sujet...
Partager