FASTCOLLECTION ==> UNE COLLECTION 10000 FOIS PLUS RAPIDE EN LECTURE PAR INDEX QU

violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 - 27 mai 2007 à 15:16
BLUEBIBUBBLE Messages postés 116 Date d'inscription samedi 4 juin 2005 Statut Membre Dernière intervention 10 avril 2013 - 2 juin 2007 à 19:27
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/42861-fastcollection-une-collection-10000-fois-plus-rapide-en-lecture-par-index-que-celle-de-vb

BLUEBIBUBBLE Messages postés 116 Date d'inscription samedi 4 juin 2005 Statut Membre Dernière intervention 10 avril 2013 1
2 juin 2007 à 19:27
Slt,
Bon travail tous, on pourrais obtenir un p'tit peu plus de précision sur le timing lors des tests en attendent la fin de la ms en cours avant chaque test, un truc du genre:

t2 = WaitTickCount
For x = 1 To 10000
...
Next x
t2 = GetTickCount - t2

t3 = WaitTickCount
For x = 1 To 100000
...
Next x
t3 = GetTickCount - t3

Function WaitTickCount() As Long
Dim T As Long
T = GetTickCount
Do: Loop While T = GetTickCount
WaitTickCount = GetTickCount
End Function
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
1 juin 2007 à 12:20
Merci ;)
@+
waluigii Messages postés 35 Date d'inscription vendredi 18 mai 2007 Statut Membre Dernière intervention 5 janvier 2008
1 juin 2007 à 02:27
Slt,

Formidable ce code...tu mérites une note de 10/10!
Continue le beau travail.=)

@+ Bon succès à toutes et à tous.
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
29 mai 2007 à 19:13
Yep c'est vrai, j'ai mis un On Error... pour éviter le bug : la Collection VB gère pas les Index incohérents ;)

En fait je ne l'ai pas précisé, mais le mieux pour tester les diverses classes et leur vitesse est d'appuyer sur les boutons dans l'ordre de haut vers le bas.

@+
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 mai 2007 à 13:31
Pour le "ajouter 10000 au début", ca coince avec la VbCollection parce que tu dit d'ajouter l'element après l'element 1... et que la liste est vide => CRASH
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
29 mai 2007 à 13:24
Yep, je retiens l'histoire des appels aux tableau à éviter (Ubound, redim...), idem que les procédures inutiles quand appelées une seule fois ^^
Par contre ta collection est encore bien plus rapide que la mienne pour le Clear (même si j'ai repris ta méthode avec le Step 4 ? bizarre.)


Au passage j'ai remarqué que la Collection de VB était limitée en nombre d'objets (ne gère pas le 'ajouter 100000 au début').

Merci encore, @+
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
29 mai 2007 à 09:06
Pas sur que la FastCollection MAJ soit bien plus lente que ce que je t'ai fourni...
j'y ai vu les améliorations que je t'avais soufflées...

bonne assimilation, j'espère que tu y repensera pour tes prochains codes ...
limiter les accès aux tableaux, les redim, les calculs inutiles...

++
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
28 mai 2007 à 21:40
Yep, je l'ai corrigé ;)

MAJ : j'ai modifié ma source en prenant en compte les conseils de Renfield, et j'ai également ajouté littéralement la classe qu'il a codée ==> elle est plus rapide et mieux commentée.


J'ai pas trop trop le temps ce soir (révisions interro p:), mais 1 amélioration à faire :
- l'implémentation de For Each (chaud pour mon niveau, mais bon)


Note : j'ai ajouté Erase comme le disait PCPT et j'ai par contre laissé Redim lPtr(n) et pas (1 to n), même si l'item 0 est pas utilisé : le (n) est très légèrement plus rapide que le 1 to n, et je rajouterais par la suite la possibilité d'utiliser l'item 0.

@+
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
28 mai 2007 à 20:33
>> "Byval varptr(Obj) => Obj" ==> bah, c'est équivalent, non ?

Non ! ce n'est pas equivalent car VarPtr est une fonction de msvbvmxx.dll par consequent tu fais un appel de plus.
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
28 mai 2007 à 20:32
Yep, d'autant que Renfield m'a proposé une version optimisée et très commentée que je releaserais avec la mienne (que je vais également optimiser suivant ses conseils).

Par contre il va manquer un truc : l'implémentation du For Each. Après m'être pas mal renseigné dessus, je dois dire que c'est pas encore de mon niveau -__-
Implémenter IEnumVARIANT etc..., n'est pas chose aisée.
ShareVB l'explique ici : http://www.vbfrance.com/tutorial.aspx?ID=188 mais je dois dire que quand il s'agit d'une collection perso (pas à base de Collection de VB), c'est bien tendu...
"pour l'implémentation du For Each, je le mettrais également" ==> ERF, je pensais pas que c'était si chaud.

Je pourrais bien sur faire un bête copier/coller d'une solution fonctionnelle, mais c'est pas le but non plus !

Donc MAJ pour les optimisations, mais le For Each pas pour tout de suite, je le ferais quand je maitriserai suffisement.

@+
apxa Messages postés 188 Date d'inscription mercredi 15 mai 2002 Statut Membre Dernière intervention 25 avril 2009
28 mai 2007 à 20:18
iop all,
Voila une source et des remarques très interressantes.
Je pense en effet qu'en travaillant un peu sur les API de windows on pourrait vraiement faire quelque chose qui serait beaucoup plus performant que le composant collection.

Hava Fun ;)
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
28 mai 2007 à 12:57
Salut, merci pour les commentaires. Alors :

- "tu pourrais accelerer la chose en stockant la taille du tableau ... ainsi, moins de UBound" ==> oui, pourquoi pas
- "Byval varptr(Obj) => Obj" ==> bah, c'est équivalent, non ?
- pour l'implémentation du For Each, je le mettrais également
- pour l'histoire du tmp, c'est pas très clair en effet, je mettrais à jour
- "ton add 1000 au début" ==> oui je sais
- "supprimant les 1000 premiers items, tu supprime en fait les elements :" ==> ah ok, problème important, j'avais pas vu.


Merci, @+
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 mai 2007 à 07:18
pour le Tmp, pour que ce soit plus clair (je voyais pas pourquoi tu modifies Obj...)

fais plutot :

Set Tmp = Obj
lPtr(Index...) = ObjPtr(Tmp)
CopyMemory Tmp, 0,4

plus clair, non ?


ton add 1000 au début en boucle ne fais RIEN du tout, si lancé au démarrage de l'appli (si la collection est vide...)
si on ajoute le test adequat, l'insertion est nettement plus rapide.

de même, gaffe au fait que ta suppression se fait dans l'ordre croissant... supprimant les 1000 premiers items, tu supprime en fait les elements :
1, 3, 5, 7, 9, ..... vu que tu décale ton tableau...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 mai 2007 à 06:37
j'aime pas trop le fait que les index commencent à 1

J'ai ajouté deux trois trucs, qui optimisent un peu la chose :
- lSize ce qui m'evite des Ubound
- lSteps qui me permet de faire le redim en cas de suppression, sans faire de Mod ni de division


VB / TOI / MOI
Ajouter 10000 a la fin :
78ms / 78 ms / 47 ms

Ajouter 1000 au début :
15ms / 109ms / 78ms

Supprimer 1000 premiers:
47ms / 78ms / 46ms

Clear:
328ms / 546ms / 62ms

Mon code n'est pas parfait, loin de là, mais montre la mise en oeuvre d'optimisations simples... et efficaces.

chose amusante, j'ajoute un element, et je ne peux pas le supprimer...
If Index > 0 And Index < lCount Then
(lCount vaut 1, ici)... a moins de mettre un Index décimal...

après relecture, j'ai saisi le role de tmp dans le Add... il sert à piquer une reference vers ton objet
j'ai testé (en mettant un BP dans le Class_Terminate de tes items), le RefCount est correct, et bien géré
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
28 mai 2007 à 05:56
lu le code, y'a des incohérences...

quand tu remove un item, tu resize ton tableau qq soit ton UpStep.

amélioration possible : tu pourrais accelerer la chose en stockant la taille du tableau ... ainsi, moins de UBound

implementes _NewEnum

Byval varptr(Obj) => Obj (me semble)

Pas compris ce que tu fais avec ton refCount dans le Add... (le role de tmp, quoi... Explique ta demarche en commentaire dans le code
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
27 mai 2007 à 22:17
lol ;)
@+
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
27 mai 2007 à 21:59
BruNews> Hahah, on ce crois a l'abri derriere une source en vb sans defence et paf ! V'la le Bruno tapi dans l'ombre mais guetant le programmeur en etat de faiblesse pour lui sortir la petite phrase assassine "qui va bon" !

Bon je te ramene bidon d'arabica de huit litre ça te fera l'apres-midi :p
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
27 mai 2007 à 20:49
EB, ce sera avec un bon café serré pour moi.
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
27 mai 2007 à 20:42
Ouai ça depend comment tu gere ton tableau, si tu fais ça comme un cake c'est clair autant telecharger ta source. En meme temps ya pas que des cakes dans la communauté vb

:p
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
27 mai 2007 à 18:57
Roohh, tu n'as pas compris l'utilité du code ;)

L'intérêt par rapport à un tableau, c'est de pouvoir insérer des Items au milieu sans avoir à redimensionner... autrement dit c'est pratiquement instantané (comme pour la Collection de VB), contrairement au tableau.
De même pour la suppression d'un Item au milieu ;)

Et cet intrêt est très important (c'est pour çà que j'ai codé çà)

@+
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
27 mai 2007 à 18:53
Ouai en fait c'est un tableau d'objet ! lol
Par ce que justemlent ce qui est interresant dans une collection c'est de pouvoir utiliser des clefs de type string car sinon autant utiliser un tableau. Mais c'est bien de l'avoir montré et codé.

:p
violent_ken Messages postés 1812 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 26 octobre 2010 2
27 mai 2007 à 15:16
Note : j'ai défini une constante arbitraire (Private Const USTEP As Long = 1000).

Si vous augmentez sa valeur, ce sera encore plus rapide mais vous perdrez peut être quelques octets en mémoire.

A l'inverse, si vous diminuez, ce sera plus lent mais gaspillera moins de mémoire.

@+
Rejoignez-nous