15. januar 2008 - 14:36Der er
10 kommentarer og 1 løsning
TComboBoxEx er langsom
Jeg bruger Delphi 7
Jeg bruger .Items.Add() i TComboBoxEx til at indsætte tekster, desværre er TComboBoxEx ca. 4 gange som langsom som TComboBox. Noget der har en løsning på hvordan man får mere fart på TComboBoxEx?
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Du kender sikkert BeginUpdate og EndUpdate, ikke? Det speeder tingene op med en faktor 2. Det hurtigste var om du kunne arbejde med et "vindue" som i TListView hvor den let kan sættes op til at vise et udsnit af en bagvedliggende liste. Et TListView går normaæt i koma når der kommer flere end 1000 linjer. Med et vindue var der ingen begrænsning for man skulle kun koncentrere sig om at vise de, ja de der skulle vises. Hvis man kan samme med TComboBoxEx er det klar løsningen - men jeg prøver lige at kigge på komponenten.
Det er nu ikke fordi det giver den store forskel at lave Begin- og EndUpdate. Ved indsættelse af 10000 linjer tog det stort set samme tid (1s)
Hvis du kender antallet først mener jeg der er en capacity-property du kan sætte. Den har godtnok aldrig hjulpet mig, men hjælpen skriver at det går hurtigere.
Har også skimmet hele arvehierarkiet igennem og sådan en TCollectionItem nedarver mange gange. Jeg kan umiddelbart ikke se hvor der er noget at hente. Der bliver ikke fyret events af når man indsætter og der er ingen synlig virkning ved brugen af Begin-/EndUpdate.
På den anden side synes jeg heller ikke den yder så dårligt. Jeg indsatte 10000 linjer og det tog under 1 sekund. Hvor mange linjer sætter du ind? Hvor lange er de enkelte linjer? Hvor kopierer du fra, en TStringList?
Der indsættes ca. 33000 linier som nok i gennemsnit er 50 tegn lange. De kommer fra en database (MySQL) men når de skal indsættes er det fra en TStringList men jeg har prøvet lidt forskellig og resultatet er det samme, det er selve indsættelsen af data i boxen der tager tiden, f.eks. tager dette næsten den samme tid (8 sekunder):
ComboBoxEx1.Items.BeginUpdate; for i:=1 to 33000 do ComboBoxEx1.Items.Add('jwsos jde je doeo d jfj jowij jd woijoijdoije dwef efe'); ComboBoxEx1.Items.EndUpdate;
Det er en lang række navne der indsættes og det virker på den måde at når brugeren begynder at indtaste et navn så foreslår TComboBoxEx de navne der er passer til det indtastede således at man ikke behøver at indtaste hele navnet. Jeg kan ikke komme på andre muligheder en TComboBoxEx til at løse denne opgave.
Hvad med en TEdit hvor du laver opslaget i en bagvedliggende TStringList. Jeg har denne løsning ved mine postnumre.
procedure TfrmePostBy.ePostByKeyPress(Sender: TObject; var Key: Char); var Edit : TEdit; begin if Key >= #32 then if not (char(CharUpper(PChar(Key))) in ['A'..'Z','Æ','Ø','Å',#32]) then Key := #0;
if ord(Key) = VK_BACK then begin Edit := Sender as TEdit; if Edit.SelLength > 0 then begin if Edit.SelStart > 0 then Edit.SelStart := Edit.SelStart - 1; Edit.SelLength := MaxInt; if Edit.SelStart = 0 then begin Edit.Text := ''; ePostNr.Text := ''; Key := #0; end; end; end; end;
procedure TfrmePostBy.ePostNrChange(Sender: TObject); var Index : integer; SelStart : integer; begin if fSkip then // Mutex da jeg ellers trigger events i den anden TEdit exit;
SelStart := ePostNr.SelStart;
fPostData := nil; Index := DM.PostList.IndexByPostnrNearest(ePostNr.Text); if Index >= 0 then fPostData := DM.PostList[Index];
if assigned(fPostData) then begin fSkip := true; try ePostNr.Text := fPostData.PostNr; ePostNr.SelStart := SelStart; ePostNr.SelLength := MaxInt; ePostBy.Text := fPostData.PostBy; finally fSkip := false; end; end; end;
procedure TfrmePostBy.ePostNrEnter(Sender: TObject); begin DM.PostList.SortByPostNr; end;
Jeg tror jeg har prøvet alle muligheder, .text:=, .Commatext:=, assign osv. Måske skulle man prøve at lave en selv, eller også må folk købe en hurtigere computer hvis de syntes det går for langsom. Men en hjemmelavet en burde jo kunne laves så det kun tager de 63 milisekunder i stedet for 6-8 sekunder, strengene jeg henter fra MySQL er sorteret i alfabetisk orden. Eller det kan faktisk laves så det tager 0 sekunder ved bare at linke til den TStringList der allerede indeholder alle strengene.
Hvad med at skjule at du fylder i listen vha. en tråd? Det er ikke det kønneste men det kan jo være brugerne ikke er nået ned til comboen inden de 8 sekunder.
Hvis du skal linke til den bagvedliggende liste må du vist i gang med at nedarve en TComboBox. Det kan være der er nogle "protected" attributter og metoder du kan bruge.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.