You are never going to get this to scale well to large amounts of data. The problem is that trying to get the string grid control to hold huge amounts of data is asking it to do something it was not designed for. Doing so results in an incredibly inefficient storage of the data.
Instead what you really need is the virtual data paradigm. Instead of having the control store the data that it displays, let the control ask you for data on demand. When it needs to know what to display it asks you. That saves you having to load it up in advance with information, most of which it never uses.
Perhaps the ideal control for your needs would be Mike Lischke's famous virtual tree view. As a simpler demonstration of the power of this paradigm, here's a simple example using TListView
.
Some initial declarations:
const
ColCount = 16;
CharactersPerCell = 4;
LoremIpsum = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod '+
'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, '+
'quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '+
'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu '+
'fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in '+
'culpa qui officia deserunt mollit anim id est laborum. ';
Setting the control's properties, and making a large string:
var
Data: string;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
while Length(Data)<20*1000*1000 do begin // 20 million characters
Data := Data + LoremIpsum;
end;
ListView1.ViewStyle := vsReport;
ListView1.OwnerData := True;
ListView1.OnData := ListViewData;
ListView1.Items.Count := 1 + (Length(Data)-1) div (ColCount*CharactersPerCell);
ListView1.Columns.Clear;
for i := 0 to ColCount-1 do begin
ListView1.Columns.Add.Caption := IntToStr(i+1);
end;
end;
Rather than using a global var stuffed full of nonsense, you might load the text from a file.
The code to fetch the data on demand:
procedure TForm1.ListViewData(Sender: TObject; Item: TListItem);
var
Row: string;
ColIndex: Integer;
begin
Row := Copy(Data, 1 + Item.Index*ColCount*CharactersPerCell, ColCount*CharactersPerCell);
Item.Caption := Copy(Row, 1, CharactersPerCell);
for ColIndex := 1 to ColCount-1 do begin
Item.SubItems.Add(Copy(Row, 1 + CharactersPerCell*ColIndex, CharactersPerCell));
end;
end;
Using a virtual contol gives performance in the display aspect. You will still have an issue with loading the data into memory. If you wish to be able to operate on huge files then you'll need to avoid loading the entire file into memory. Instead load only portions of the file, again on demand.