Could somebody with access to the coming Delphi 10.2(?) please test this and maybe update this or post a new report:

Could somebody with access to the coming Delphi 10.2(?) please test this and maybe update this or post a new report:

TBufferedFileStream Seek performance is less than optimal

The implementation for TBufferedFileStream.Seek could be improved a lot by first checking whether the new position is still within the buffer. Currently it always writes the current buffer to the file and then rereads it at the new position. This results in two unnecessary I/O operations and makes the buffer useless e.g. when writing backwards or with gaps.

Steps:
1. Create a new VCL-Application, add a memo and a button

2. For add an OnClick event for the button as:
procedure TForm1.Button1Click(Sender: TObject);
begin
TestBackwards(0);
TestBackwards(1024);
end;

3. Add the following TestBackwards method:
procedure TForm1.TestBackwards(_BufSize: integer);
var
st: TBufferedFileStream;
i: Integer;
b: Byte;
Start: Cardinal;
Ticks: Cardinal;
begin
m_Output.Lines.Add(Format('Writing file with buffer size %d', [_BufSize]));
Start := GetTickCount;
st := TBufferedFileStream.Create('d:\bufferedtest.bin', fmCreate or
fmShareExclusive, _BufSize);
try
for i := 1024 * 1024 - 1 downto 0 do begin
b := i mod 256;
st.Position := i;
st.WriteBuffer(b, SizeOf(b));
end;
finally
FreeAndNil(st);
end;
Ticks := GetTickCount - Start;
m_Output.Lines.Add(Format('done. Took %.3f seconds', [Ticks / 1000]));
end;

4. Compile and run

5. Click the button
The programm will write to the memo something like this:
Writing file with buffer size 0
done. Took 2,610 seconds
Writing file with buffer size 1024
done. Took 4,828 seconds

6. Change the for loop to count upwards from 0 to 1024*1024-1 instead of downwards and you get something like this:
Writing file with buffer size 0
done. Took 2,594 seconds
Writing file with buffer size 1024
done. Took 0,031 seconds
https://quality.embarcadero.com/browse/RSP-17025

Comments

  1. Unfortuntely David Heffernan 's implementation
    stackoverflow.com - Buffered files (for faster disk access)
    Isn't any faster in this case. I had hopes.
    (I admit that writing a file stream backwards is not the most prevalent use case, it just was the worst case I could think of.)

    ReplyDelete
  2. Someone with access to the coming 10.2 release could not say he/she has access to it in the past :)

    ReplyDelete
  3. Horácio Filho As everyone with Update Subscription has access to the beta, saying that one is under Update Subscription implies that one has access to the beta.

    ReplyDelete
  4. Uwe Raabe I forgot that :) Sorry at all.

    ReplyDelete
  5. BTW, initially this class was in FireDAC, then was moved to RTL. It was conforming to FireDAC usage patterns, which mostly are writing / reading of small data chunks in consecutive way. Of course, it may be optimized for more usage patterns.

    ReplyDelete
  6. It's just that the documentation doesn't say anything about this. The htmlhelp of Delphi 10.1 Upd2 doesn't even have it in the index, you heave to search for the keyword.

    ReplyDelete
  7. From my own buffered stream Seek implementation:

    // TODO - more intelligent handling of buffer
    ClearBuffer;

    Seems I'm not alone :)

    ReplyDelete

Post a Comment