LcfReader: Cache the file offset
Calls to ifstream::tellg() all resolve to lseek64() system
calls on linux. Our code calls tellg() quite often, so cache
the value locally.
Tests show this change resulting in 35% reduction in loading time
for a large ldb.
MODIFY
src/reader_lcf.cpp
src/reader_lcf.cpp
@@ -21,6 +21,7 @@ LcfReader::LcfReader(std::istream& filestream, std::string encoding)
: stream(filestream)
, encoder(std::move(encoding))
{
+ offset = filestream.tellg();
}
LcfReader::~LcfReader() {
@@ -32,7 +33,9 @@ size_t LcfReader::Read0(void *ptr, size_t size, size_t nmemb) {
}
//Read nmemb elements of size and return the number of read elements
stream.read(reinterpret_cast<char*>(ptr), size*nmemb);
- size_t result = stream.gcount() / size;
+ auto bytes_read = stream.gcount();
+ offset += bytes_read;
+ size_t result = bytes_read / size;
#ifdef NDEBUG
if (result != nmemb && !Eof()) {
perror("Reading error: ");
@@ -198,12 +201,15 @@ void LcfReader::Seek(size_t pos, SeekMode mode) {
switch (mode) {
case LcfReader::FromStart:
stream.seekg(pos, std::ios_base::beg);
+ offset = stream.tellg();
break;
case LcfReader::FromCurrent:
stream.seekg(pos, std::ios_base::cur);
+ offset = stream.tellg();
break;
case LcfReader::FromEnd:
stream.seekg(pos, std::ios_base::end);
+ offset = stream.tellg();
break;
default:
assert(false && "Invalid SeekMode");
@@ -211,7 +217,14 @@ void LcfReader::Seek(size_t pos, SeekMode mode) {
}
uint32_t LcfReader::Tell() {
- return (uint32_t)stream.tellg();
+ // Calling iostream tellg() results in a system call everytime and was found
+ // to dominate the runtime of lcf reading. So we cache our own offset.
+ // The result of this was shown to have a 30-40% improvement in LDB loading times.
+ // return (uint32_t)stream.tellg();
+ // This assert can be enabled to verify this method is correct. Disabled by
+ // default as it will slow down debug loading considerably.
+ // assert(stream.tellg() == offset);
+ return offset;
}
int LcfReader::Peek() {

MODIFY
src/reader_lcf.h
src/reader_lcf.h
@@ -216,6 +216,8 @@ public:
private:
/** File-stream managed by this Reader. */
std::istream& stream;
+ /** Cached file stream offset */
+ int64_t offset;
/** Contains the last set error. */
static std::string error_str;
/** The internal Encoder */

LcfReader: Cache the file offset

Calls to ifstream::tellg() all resolve to lseek64() system
calls on linux. Our code calls tellg() quite often, so cache
the value locally.

Tests show this change resulting in 35% reduction in loading time
for a large ldb.