violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 2010
-
24 mai 2007 à 18:29
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 2010
-
27 mai 2007 à 15:08
Violent Ken
Salut, à tous ;)
J'ai un petit problème : l'accès aux objets d'une collection est très lent pour les objets dont l'index est élevé...
Exemple : code 1, on accède à 30000 objets, 1000 fois les 30 premiers
Le temps d'accès est très rapide (phase de récupération avec .Item)
Private Sub Command1_Click()
Dim o As Collection
Dim x As Long
Dim y As Long
Dim k As Object
Set o = New Collection
Debug.Print "adding..."
For x = 1 To 30000
o.Add k
Next x
Debug.Print "retrieving..."
For x = 1 To 30
For y = 1 To 1000
Set k = o.Item(x)
Next y
Next x
Debug.Print "done"
Exemple : code 2, on accède à 30000 objets, mais cette fois les 30000 de la collection ==> TRES lent...
Private Sub Command1_Click()
Dim o As Collection
Dim x As Long
Dim y As Long
Dim k As Object
Set o = New Collection
Debug.Print "adding..."
For x = 1 To 30000
o.Add k
Next x
Debug.Print "retrieving..."
For x = 1 To 30000
'For y = 1 To 1000
Set k = o.Item(x)
'Next y
Next x
Debug.Print "done"
cs_DARKSIDIOUS
Messages postés15814Date d'inscriptionjeudi 8 août 2002StatutMembreDernière intervention 4 mars 2013130 24 mai 2007 à 19:00
normal, la collection est bien connue pour être lente dès que le nombre d'objet devient important (je me demande comment c'est implémenté, mais c'est sûrement une liste chaînée).
La solution ? Pourquoi ne pas essayé d'éclater ta collection en 10 ou 100 : l'accès aux objets pourrait être bien plus rapide je pense.
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 26 mai 2007 à 08:05
tout dépend de combien d'octets tu décale la chose...
si ca ne crashes pas, c'est deja bon signe
ensuite, j'ignore s'il aime bien bien lire et ecrire sur des zones mémoires qui se chevauchent, m'enfin....
au pire, tu peux te faire un tableau de pointeurs vers tes objets, mais là, pareil, faudrait que la recherche par clé soit relativement rapide...
peut etre avec un hash....
a voir, quoi ^^ sujet très vaste.
y'a quelques années, j'etais tombé sur un code sur le net, qui faisait des sortes de power collections, je cite (presque) "super rapides", "super pratiques", etc
Et si tu veux un exemple simple d'utilisation, je l'utilise (bien que pas beaucoup d'objets) dans ma source pour le suivi des actions.
Indice : regarde le membre caché d'une collection dans l'explorateur d'objet : _NewEnum
@++
<hr size="2" width="100%" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 24 mai 2007 à 18:42
Violent Ken
Salut, merci pour la réponse rapide ;)
Mais en fait j'ai simplifié l'énoncé de mon problème... j'ai déjà une classe objet (contenant la collection) qui implémente For Each...
For Each est bien pour parcourir tous les objets, mais mon vrai problème c'est que je veux parcourir par exemple les 50 derniers objets de la collection et le temps est beaucoup plus élevé que pour les 50 premiers...
Concrêtement, dans l'espèce de ListView que je code, le scroll se met à ramer à mort quand on passe vers les Items situé à la fin de la liste, à cause du temps d'accès à la collection.
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 24 mai 2007 à 19:02
J'ai du mal à comprendre, comment tu fais ici :
Set o = New Collection
Debug.Print "adding..."
For x = 1 To 30000 o.Add k ' là tu ajoutes k, alors qu'il n'est instancié dans l'autre boucle
Next x
Debug.Print "retrieving..."
For x = 1 To 30000 'For y = 1 To 1000
Set k = o.Item(x)
'Next y
Next x
Debug.Print "done"
@++
<hr size ="2" width="100%" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 24 mai 2007 à 19:07
Violent Ken
Merci pour l'info sur la lenteur de la collection.
Pour l'éclatement de la collection, sûr que c'est une solution, mais çà me semble difficile à mettre en oeuvre. Sachant que je code une sorte de ListView, avec l'objet vkListItem et l'objet collection vkListItems. C'est pour çà que je vois pas trop comment je pourrais subdiviser la ListItems en plusieurs collections ?
Mortalino ==> pas besoin d'instancier, c'est à Nothing par défaut. Alors j'affecte un objet vide, mais peu importe, c'est la récupération qui m'intéresse dans cet exemple.
Note :
Private Sub Command1_Click()
Dim obj As Object
MsgBox (obj Is Nothing)
End Sub , ----
By Renfield @+
Renfield
Messages postés17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 25 mai 2007 à 08:46
Tu pourrais utiliser un simple tableau pour stocker tes objets...
en désactivant les controles sur les tableaux (options de compilation) ca devrait le faire...
la chose étant que le .Item des collection est lent... il doit regarder ce que tu transmet (clé ou index) et faire la recherche en interne... j'ignore la structure de la chose, reste que c'est connu comme étant lent.
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 25 mai 2007 à 12:02
Violent Ken
Salut Renfield !
En fait j'utilise déjà des tableaux (notamment pour les propriétés Checked et Selected de mon objet), mais le problème est l'insertion d'un Item avec un index différent du nombre total d'items (en gros, si je veux pouvoir ajouter un item au millieu, je dois reclasser tout le tableau). Avec un collection (donc sûrement une liste chaînée), il n'y avait pas le problème.
Je vais voir ce soir, merci pour l'info en tout cas.
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 25 mai 2007 à 13:17
Violent Ken
Re, en fait j'ai eu une idée mais je ne sais pas si c'est réalisable : serait-il possible de pouvoir déplacer les Items d'un tableau sans passer par des boucles For, mais plutôt par l'instruction CopyMemory ? (on décale des bytes en mémoire et on peut après insérer le nouvel Item au milieu).
@+
Hex Editor VB
violent_ken
Messages postés1812Date d'inscriptionmardi 31 mai 2005StatutMembreDernière intervention26 octobre 20102 25 mai 2007 à 21:46
Violent Ken
Salut tout le monde, j'ai presque réussi à trouver une parade : je passe par une liste et un copymemory pour pouvoir éviter de faire des For pour le décalage (quand on ajoute un Item au milieu de la liste).
Seul problème, je n'arrive pas à trouver une erreur dans mon code :(
Elle se situe dans la sub RemoveItem, mais j'ai beau avoir cherché pendant 1h, j'ai pas trouvé...
Est-ce que quelqu'un manie avec facilité les CopyMemory et pourrait m'aider à fixer ce léger bug ? (pour voir le bug, ajouter des items à index=2, puis enlever des items à index=2, un "décalage" apparait)