Copying an entire contents of TCustomDADataSet to TVirtualTable row-by-row
Posted: Tue 27 May 2008 19:45
Hi,
I'm looking for a faster way to do this:
Please bear in mind that this is a contrived example. In real code I'm sending rows in batches from a background thread to the UI, so it's a requirement that I do it row-by-row. Since SrcDataSet can contain a large number of records (hundreds of thousands), this loop with Variant-based copying of values makes for a considerable overall slowdown (I confirmed it with a profiler).
Field structures of both datasets are identical, so I believe it should be possible to somehow directly assign row buffers from SrcDataSet to DstDataSet. I've tried experimenting with this code:
It runs fine, but DstDataSet doesn't seem to see the changes - all fields in the DstDataSet have Null values afterwards.
Is there any other way? I don't mind changing the source, if necessary. I want to avoid the unnecessary looping, variant-based assignments and intermediate buffering of any kind. I also wish to avoid triggering as many events and internal checks in both datasets as possible in order to gain speed.
Access is strictly sequential and datasets are identical copies, as seen from my example above, so error checking and nulling field values before copying them (which Append does internally) is all completely superfluous.
I suspect the solution, if it exists, will be close to what I did above with ActiveBuffer assignment, but probably with additional manipulation of the internal Data of the DstDataSet (which is TVirtualTable), so that changes become visible to DstDataSet clients.
Any help will be greatly appreciated. Thanks in advance!
I'm looking for a faster way to do this:
Code: Select all
while not SrcDataSet.Eof do begin
DstDataSet.Append;
try
for I := 0 to SrcDataSet.FieldCount - 1 do
DstDataSet.Fields[I].Value := SrcDataSet.Fields[I].Value;
finally
DstDataSet.Post;
end;
SrcDataSet.Next;
end;
Field structures of both datasets are identical, so I believe it should be possible to somehow directly assign row buffers from SrcDataSet to DstDataSet. I've tried experimenting with this code:
Code: Select all
DstDataSet.Append;
try
Move(SrcDataSet.ActiveBuffer^, DstDataSet.ActiveBuffer^, SrcDataSet.RecordSize);
finally
DstDataSet.Post;
end;
Is there any other way? I don't mind changing the source, if necessary. I want to avoid the unnecessary looping, variant-based assignments and intermediate buffering of any kind. I also wish to avoid triggering as many events and internal checks in both datasets as possible in order to gain speed.
Access is strictly sequential and datasets are identical copies, as seen from my example above, so error checking and nulling field values before copying them (which Append does internally) is all completely superfluous.
I suspect the solution, if it exists, will be close to what I did above with ActiveBuffer assignment, but probably with additional manipulation of the internal Data of the DstDataSet (which is TVirtualTable), so that changes become visible to DstDataSet clients.
Any help will be greatly appreciated. Thanks in advance!