Page 1 sur 1

Défi : faire le code le plus rapide pour remplir une combo

Publié : mar. 07/févr./2006 14:01
par olivier
Voilà j'ai besoins d'accélérer le remplissage d'une comboGadget à partir d'un fichier txt regroupant une liste de ville.

Ce code crée un fichier test.txt avec le nom des villes. Puis suivant les diffférent cas traite le problème.

Le cas 1 est le cas basique.
Le cas 2 est le meilleur que j'ai réussi à obtenir.

J'attends vos idée pour un troisième code plus rapide....

Merci d'avance

Code : Tout sélectionner

Procedure ess1()
    SetGadgetText(52,"en cours")
    ClearGadgetItemList(50)
    temps=GetTickCount_() 
    ReadFile(0,"test.txt")
    fin=Lof() 
    Repeat
        AddGadgetItem(50,-1,Trim(Left(ReadString(),50)))
    Until Loc() =fin
    CloseFile(0)
    SetGadgetText(52,Str(GetTickCount_()-temps ))
    SetGadgetState(50,0)
EndProcedure
    
Procedure ess2()
    SetGadgetText(52,"en cours")
    ClearGadgetItemList(50)
    temps=GetTickCount_() 
    ReadFile(0,"test.txt")
    *Tampon=AllocateMemory(Lof())
    ReadData(*Tampon,Lof())
    fin=Lof()/72 
    CloseFile(0)
    
    id_gadget=GadgetID(50)
    
    For i=0 To fin
        SendMessage_(id_gadget , #CB_ADDSTRING, 0, Trim(PeekS( *Tampon+i*72,50)))
        ;AddGadgetItem(50,-1,Trim(PeekS( *Tampon+i*72,50)))
    Next
    
    
    SetGadgetText(52,Str(GetTickCount_()-temps ))
    SetGadgetState(50,0)
    
EndProcedure
    
Procedure ess3()
    SetGadgetText(52,"en cours")
    ClearGadgetItemList(50)
    temps=GetTickCount_() 
    
    ;-----------votre code--------------
    
    ;-----------fin de votre code--------
    
    SetGadgetText(52,Str(GetTickCount_()-temps ))
    SetGadgetState(50,0)
EndProcedure

;{-creation de la fenetre
hwindow=OpenWindow(0,10,10,200,200,#PB_Window_SystemMenu,"ess")
CreateGadgetList(WindowID(0))
    
ComboBoxGadget(50, 0,0, 200, 200)

TextGadget(52,0,50,200,20,"temps")
    
ButtonGadget(1,10,100,20,20,"1")
ButtonGadget(2,30,100,20,20,"2")
ButtonGadget(3,50,100,20,20,"3")
;}

;{- creation du fichier test : nom de ville sur 50 caractere + coordonnee sur 22    
CreateFile(0,"test.txt")
For i=1 To 35000
    nom_ville$=LSet("Nom de la ville numérotée : "+Str(i),50)
    WriteStringN(nom_ville$+"12345678901234567890")
Next   
CloseFile(0)
    ;}

Repeat
    event=WaitWindowEvent()
    Select event
        Case #PB_Event_Gadget; *****************Choix d'un bouton
            Select EventGadgetID()
                Case 1
                    ess1()
                Case 2
                    ess2()
                Case 3
                    ess3()
            EndSelect
    EndSelect
Until event=#WM_CLOSE


Publié : mar. 07/févr./2006 15:21
par Backup
..

Publié : mar. 07/févr./2006 15:25
par Backup
l'avantage de la liste chainée intervien lorsque l'on reclick a nouveau sur le bouton , puisque la liste est deja en memoire, ya pas a relire la fichier a chaque fois !!

de meme pour les operations de trie eventuel , en mémoire ça va plus vite
une liste chainée c'est des pointeurs avant tout ! :D

sinon ton system de pointeur va tres vite deja , et n'oublie pas que la V4
tamporise l'acces au fichié , ce qui devrai accelerer encore je pense ! :D

Publié : mar. 07/févr./2006 15:27
par olivier
Tu ne tricherais pas un petit peu :roll:

La procedure doit contenir l'ouverture du fichier !!!

Mais merci quand même.

Publié : mar. 07/févr./2006 18:55
par Fred
Oui, pour la commande ReadString() on peut facilement avoir un facteur 10-20 entre la v3.94 et la v4.

Publié : mar. 07/févr./2006 22:52
par Flype
Essayes aussi un HideGadget(ComboID,#True) avant la boucle de chargement et ensuite un HideGadget(ComboID,#False).
J'utilise ce 'trick' avec PB3.x dans un ListIconGadget et çà boosst le chargement.

Publié : mar. 07/févr./2006 23:21
par nico
J'ai essayé différentes choses mais je n'ai pas réussi à faire mieux que toi.

Je me suis rendu compte qu'en fait c'est le chargement de la combobox qui est très long et proportionnel à la longueur du texte donc on ne peut pas obtenir de bons résultats.

Je crois que c'est le cas typique où créé son propre gadget serait bien utile dans ce cas là.

Le mieux serait d'afficher soi-même un listview et de gérer le remplissage au fur à mesure que l'on clique sur la barre de navigation; mais ça doit pas être simple.

Publié : mer. 08/févr./2006 0:54
par Fred
A mon avis ca vaut le coup d'utiliser l'OwnerDraw, comme ca tu l'affiche au fur et a mesure. Elle peut alors etre aussi grande que tu veux, ca devrait aller.

Publié : mer. 08/févr./2006 1:06
par Flype
ya mieux, beaucoup mieux.

Cf. MSDN: COMBOBOX + CB_INITSTORAGE

Code : Tout sélectionner

SendMessage_(GadgetID(50),#CB_INITSTORAGE,NbItems,BufferSize)
Avec çà, juste avant ta boucle de chargement, tu boostes par 5 ou 10 ta procédure.

:D ( oui je sais çà calme - çà m'a fait çà aussi la première fois )

http://msdn.microsoft.com/library/defau ... string.asp

Publié : mer. 08/févr./2006 2:14
par Fred
Bien vu :)

Publié : mer. 08/févr./2006 8:21
par olivier
Very Happy ( oui je sais çà calme - çà m'a fait çà aussi la première fois )
:lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol:

Sur le coup cela m'a beaucoup fait rire ta remarque.

Puis viens la pratique. J'insère : SendMessage_(GadgetID(50),#CB_INITSTORAGE,NbItems,BufferSize)

Puis rien, oui forcément faut remplacer les variable par leur valeur...
SendMessage_(GadgetID(50),#CB_INITSTORAGE,0,fin*50)

Pour nbitems, j'ai mis 0 car dans MSDN il écrive :
wParam
This parameter is not used.
Et alors là !!!!!!! *20, je passe de 2000 à 100


BRAVO 8)

Flype tu as assuré ! Gràve ! Je ne m'attendais pas à un gain aussis élevé !!!


Je me demande si Fred n'aurais pas un petit message comme celui ci à envoyer dans le débuggueur pour le remplissage des valeurs des tableaux. :?

Merci à tous et bonne prog
Stef

Publié : jeu. 16/févr./2006 9:43
par Flype
Après discussion à ce sujet sur le forum officiel,
http://forums.purebasic.com/english/vie ... hp?t=19542

il en résulte que cette astuce fonctionne 'bien' uniquement si
la mémoire tampon allouée respecte cette formule :

TAILLEMEMOIRE = NBLIGNES * ( LEN(LIGNE) * 2 )

En effet, Windows stocke les lignes dans les ComboBox en Unicode.
Donc les chaines de caractères sont deux fois plus longues qu'en ASCII.
Donc pour que la fonction CB_INITSTORAGE fonctionne le mieux possible
il faut allouer la quantité de mémoire adéquate...

NB:
C'est encore plus visible avec les thèmes XP activés dans les propriétés d'affichage.

Publié : jeu. 16/févr./2006 14:25
par nico
Ben c'est vrai qu'au début , j'avais essayé ton code et je ne voyais pas la différence. C'est après ton post sur le forum anglais que je me suis rappellé qu'en fait window XP est natif unicode et qu'il travaille en unicode même si on lui donne de l'ASCII, s'occupant lui même de la conversion.

Pour 95, 98, me il n'est pas nécessaire de multiplier par 2.