Hi,
The current implementation of ftell is basically equivalent to
fseek(fp, 0, SEEK_CUR). While this is not incorrect, it results in
inheritance of limitations of fseek, which is summarized in the
following comment in the source:
/* Flush unwritten characters.
(This may do an unneeded write if we seek within the buffer.
But to be able to switch to reading, we would need to set
egptr to ptr. That can't be done in the current design,
which assumes file_ptr() is eGptr. Anyway, since we probably
end up flushing when we close(), it doesn't make much difference.)
FIXME: simulate mem-papped files. */
This is not needed for ftell since it does not need to set or
modify buffer state, so this flush can be avoided. Attached patch
computes current position for ftell (within the file_seekoff functions
as a special case) without flushing the buffers when in write mode. I
have used a modified version of the sample program in the bz (appended
to this email) to check the improvement in performance in each call and
the average reads as below on my Fedora 16 x86_64 core i5 laptop with
4GB RAM:
Without patch:
Total time: 9174470.000000 ns. AVG 1819.609282 ns per call
With patch:
Total time: 1047375.000000 ns. AVG 207.730067 ns per call
I have verified that the change does not cause any regressions in the
testsuite.
Regards,
Siddhesh
ChangeLog:
[BZ #5298]
* libio/fileops.c (_IO_new_file_seekoff): Don't flush buffer
for ftell. Compute offsets from write pointers instead.
* libio/wfileops.c (_IO_wfile_seekoff): Likewise.