VCL Delphi

Title: Increasing speed of a ListBox with 1,000,000 lines
Question: Populating the items of a ListBox can become extremely slow for a VERY large number of items. Is there a way to speed this up?
Answer:
In one of my recent projects I had to read a text file with 1 million lines to display its contents in a listbox. I started off with a procedure like
procedure TForm1.ReadFile(AFileName:string);
var
Stream : TStream;
L : TStringList;
begin
L := TStringList.Create;
Stream := TFileStream.Create(AFileName, fmOpenRead);
try
L.LoadFromStream(Stream);
Listbox.Items.Assign(L);
finally
Stream.Free;
L.Free;
end;
end;
Although reading the file (line "L.LoadFromStream(Stream)") was finished after a few instances, transferring the items to the ListBox (line "Listbox.Items.Assign(L)") took more than 5 minutes on a 2.4 GHz Pentium.
Searching for a way how to speed this up, I came upon a delphi3000 article by Alec Bergamini on virtual listboxes (http://www.delphi3000.com/articles/article_2546.asp) which finally resolved my problem. Using the Listbox in the virtual mode made reading and displaying of the 1-million-line file to a snap of only 0.8 s.
The source code modifications to work in virtual mode are relatively simple:
- In the object inspector, set "Style" to lbVirtual (or lbVirtualOwnerDraw), and set "Count" to the number of lines to be displayed
- Write a handler for the Listbox event "OnData":
procedure TForm1.Listbox1Data((Control:TWinControl; Index:integer;
var Data:string);
begin
Data := FStrings[index];
end;
This defines where the data string which is to be displayed in a line specified by "index" comes from. In this example, I'm using a TStringList ("FStrings") which needs to be declared in the private section of the form, instantiated in the form's OnCreate and destroyed in the form's OnDestroy event handlers, respectively.
That's all! An almost thousand-fold increase in speed is a great reward for this little typing exercise!