XL 2013 CreateObject("scripting.dictionary") et/ou variable tableau ?

BenHarber

XLDnaute Occasionnel
Bonjour le Forum,
J'ai trouvé la fonction VBA suivante sur développez.net (merci Mchel M) qui me permet de compter sans doublon les enregistrements d'une plage de cellules. Elle fonctionne bien (même si je ne vois pas trop à quoi CreateObject("scripting.dictionary") correspond...)

A présent, je souhaiterais utiliser les différentes valeurs trouvées dans cette plage de cellules. Je pensais pour cela les enregistrer dans une variable tableau [du type : monTab(0 à n)] : ma question est de savoir si je peux pour cela utiliser "dico" (?) ou si je dois obligatoirement créer une nouvelle variable tableau ?
Merci d'avance pour vos idées toujours constructives !
BH
Function compter_uniques(plage As Range) As Long

Set dico = CreateObject("scripting.dictionary")
For Each cellule In plage
ref = cellule.Value
If Not dico.exists(ref) Then
dico.Add ref, ref
End If
Next
compter_uniques = dico.Count
End Function
 

jmfmarques

XLDnaute Accro
Mais je vais revoir tout ça pour qu'il fasse une ligne par essai pour pouvoir faire un graphique …
C'est sage.
et ce sera encore plus sage en procédant ainsi (histoire de n'avoir que du "pur") :
1) arrêter et redémarrer windows et ne rien ouvrir d'autre que ton classeur
2) ne faire tes tests que par "séries" du même type (séries collection, par exemple) en "doublant" chaque essai et en ne gardant que la durée du second
3) arrêter et redémarrer windows et faire les mêmes opération avec l'objet dictionary.

Pourquoi ces précautions ? tout simplement pour deux raisons :
- éviter le risque de travailler en zone de swap
- éviter les aléas de la gestion de mémoire par Windows, qui "ajuste" son fichier de pagination en fonction des besoins qu'il estime (-raison pour laquelle la seconde opération de chaque doublon d'essai peut être plus performante que la première.
Bon courage.
 

Dranreb

XLDnaute Barbatruc
C'est déjà long à exécuter comme ça ce n'est pas pour établir en plus des résultats qu'on ne verra pas !
Pas très facile à analyser tout ça, mais ce que j'avais déjà entrevu se confirme, et d'autre découvertes curieuses :
— Un plancher incompressible d'1 milliseconde apparaît pour les Dictionary en liaisons tardives.
— Un curieux accroissement du temps nécessaire pour tous aux alentours de 1000 éléments et, dans une moindre mesure, de 2000
— La Collection reprend du poil de la bête au delà de 100000 éléments.
 

Dranreb

XLDnaute Barbatruc
Ce n'est pas le demandeur @BenHarber qui est en cause, c'est @jmfmarques qui a reproduit des critiques que j'ai souvent lu ailleurs à propos des collections, sans y croire vraiment faute d'avoir essayé. C'est chose faites à présent pour moi, encore que le résultat puisse dépendre de diverses conditions d'utilisation.
La vérité, je pense, c'est que tout ça se tient dans un mouchoir de poche, les différences entre Collection et Dictionary n'étant que du même ordre de grandeur que l'utilisation de ce dernier en liaisons soit tardives soit anticipées. La vraie grosse surprise c'est que la Collection semble l'emporter au delà de 100000 éléments. Je serais curieux de savoir pourquoi …
J'ai une hypothèse pas trop idiote: la clé de hachage des Collection serait plus simple à calculer parce qu'elle n'accèpte que des String.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Collection: 3,484375, Dico: 0,125. Un 2nd essai :
Collection: 3,359375, Dico: 0,15625.
Mais dans votre code l'ajout en collection inclut la conversion en String d'un Variant/Single, ce qui n'explique certes pas tout, mais en tout cas moi j'ai fait tout ce que j'ai pu pour ne tester que les fonctionnement propres des objets, et ce dans les conditions les plus similaires possibles.
De toute façon vous avez probablement déjà remarqué que pour obtenir une liste classée sans doublon j'adopte une stratégie complètement différente: je trie d'abord (j'indexe plus exactement) et j'élimine les doublons ensuite par un parcours séquentiel, vu qu'ils s'y retrouvent ensembles. J'en profite pour noter au passage les numéros de lignes où je les ai trouvés, mais ça c'est une autre histoire …
 
Dernière édition:

BOISGONTIER

XLDnaute Barbatruc
Repose en paix
Il n'y a pas photo.

La génération de 50.000 nombres avec la conversion en chaîne prend 0,03 sec

VB:
Sub Genere50000nombres()
   t = Timer()
   n = 50000
   ReDim Tbl(1 To n, 1 To 1)
   For i = 1 To n
     Tbl(i, 1) = CStr(Int(Rnd * n))
   Next i
   MsgBox Timer() - t
End Sub

Boisgontier
 

BOISGONTIER

XLDnaute Barbatruc
Repose en paix
>Collection: 3,484375, Dico: 0,125. Un 2nd essai :
>Collection: 3,359375, Dico: 0,15625


ça recoupe mes essais. Dire que Collection est plus rapide que Dico est donc bien une contre vérité comme je l'écrivais au #12.

J'ai essayé avec 100.000 mais ça ne change rien.

Boisgontier
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
312 410
Messages
2 088 162
Membres
103 752
dernier inscrit
FG2