Performance improvements to savegame loading

This commit is contained in:
Jonathan G Rennison
2018-05-28 02:22:26 +01:00
parent 8404afd40f
commit 3b83a9e186
2 changed files with 136 additions and 34 deletions

View File

@@ -320,18 +320,115 @@ struct ReadBuffer {
{ {
} }
inline byte ReadByte() void SkipBytesSlowPath(size_t bytes)
{ {
if (this->bufp == this->bufe) { bytes -= (this->bufe - this->bufp);
while (true) {
size_t len = this->reader->Read(this->buf, lengthof(this->buf)); size_t len = this->reader->Read(this->buf, lengthof(this->buf));
if (len == 0) SlErrorCorrupt("Unexpected end of chunk"); if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
this->read += len; this->read += len;
this->bufp = this->buf; if (len >= bytes) {
this->bufe = this->buf + len; this->bufp = this->buf + bytes;
this->bufe = this->buf + len;
return;
} else {
bytes -= len;
}
}
}
inline void SkipBytes(size_t bytes)
{
byte *b = this->bufp + bytes;
if (likely(b <= this->bufe)) {
this->bufp = b;
} else {
SkipBytesSlowPath(bytes);
}
}
void AcquireBytes()
{
size_t remainder = this->bufe - this->bufp;
if (remainder) {
memmove(this->buf, this->bufp, remainder);
}
size_t len = this->reader->Read(this->buf + remainder, lengthof(this->buf) - remainder);
if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
this->read += len;
this->bufp = this->buf;
this->bufe = this->buf + remainder + len;
}
inline byte RawReadByte()
{
return *this->bufp++;
}
inline byte ReadByte()
{
if (unlikely(this->bufp == this->bufe)) {
this->AcquireBytes();
} }
return *this->bufp++; return RawReadByte();
}
inline void CheckBytes(size_t bytes)
{
while (unlikely(this->bufp + bytes > this->bufe)) this->AcquireBytes();
}
inline int RawReadUint16()
{
#if OTTD_ALIGNMENT == 0
int x = FROM_BE16(*((const uint16*) this->bufp));
this->bufp += 2;
return x;
#else
int x = this->RawReadByte() << 8;
return x | this->RawReadByte();
#endif
}
inline uint32 RawReadUint32()
{
#if OTTD_ALIGNMENT == 0
uint32 x = FROM_BE32(*((const uint32*) this->bufp));
this->bufp += 4;
return x;
#else
uint32 x = this->RawReadUint16() << 16;
return x | this->RawReadUint16();
#endif
}
inline uint64 RawReadUint64()
{
#if OTTD_ALIGNMENT == 0
uint64 x = FROM_BE64(*((const uint64*) this->bufp));
this->bufp += 8;
return x;
#else
uint32 x = this->RawReadUint32();
uint32 y = this->RawReadUint32();
return (uint64)x << 32 | y;
#endif
}
inline void CopyBytes(byte *ptr, size_t length)
{
while (length) {
if (unlikely(this->bufp == this->bufe)) {
this->AcquireBytes();
}
size_t to_copy = min<size_t>(this->bufe - this->bufp, length);
memcpy(ptr, this->bufp, to_copy);
this->bufp += to_copy;
ptr += to_copy;
length -= to_copy;
}
} }
/** /**
@@ -648,6 +745,34 @@ byte SlReadByte()
return _sl.reader->ReadByte(); return _sl.reader->ReadByte();
} }
/**
* Read in bytes from the file/data structure but don't do
* anything with them, discarding them in effect
* @param length The amount of bytes that is being treated this way
*/
void SlSkipBytes(size_t length)
{
return _sl.reader->SkipBytes(length);
}
int SlReadUint16()
{
_sl.reader->CheckBytes(2);
return _sl.reader->RawReadUint16();
}
uint32 SlReadUint32()
{
_sl.reader->CheckBytes(4);
return _sl.reader->RawReadUint32();
}
uint64 SlReadUint64()
{
_sl.reader->CheckBytes(8);
return _sl.reader->RawReadUint64();
}
/** /**
* Wrapper for writing a byte to the dumper. * Wrapper for writing a byte to the dumper.
* @param b The byte to write. * @param b The byte to write.
@@ -946,7 +1071,7 @@ static void SlCopyBytes(void *ptr, size_t length)
switch (_sl.action) { switch (_sl.action) {
case SLA_LOAD_CHECK: case SLA_LOAD_CHECK:
case SLA_LOAD: case SLA_LOAD:
for (; length != 0; length--) *p++ = SlReadByte(); _sl.reader->CopyBytes(p, length);
break; break;
case SLA_SAVE: case SLA_SAVE:
for (; length != 0; length--) SlWriteByte(*p++); for (; length != 0; length--) SlWriteByte(*p++);

View File

@@ -679,24 +679,9 @@ size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
byte SlReadByte(); byte SlReadByte();
void SlWriteByte(byte b); void SlWriteByte(byte b);
static inline int SlReadUint16() int SlReadUint16();
{ uint32 SlReadUint32();
int x = SlReadByte() << 8; uint64 SlReadUint64();
return x | SlReadByte();
}
static inline uint32 SlReadUint32()
{
uint32 x = SlReadUint16() << 16;
return x | SlReadUint16();
}
static inline uint64 SlReadUint64()
{
uint32 x = SlReadUint32();
uint32 y = SlReadUint32();
return (uint64)x << 32 | y;
}
static inline void SlWriteUint16(uint16 v) static inline void SlWriteUint16(uint16 v)
{ {
@@ -716,15 +701,7 @@ static inline void SlWriteUint64(uint64 x)
SlWriteUint32((uint32)x); SlWriteUint32((uint32)x);
} }
/** void SlSkipBytes(size_t length);
* Read in bytes from the file/data structure but don't do
* anything with them, discarding them in effect
* @param length The amount of bytes that is being treated this way
*/
static inline void SlSkipBytes(size_t length)
{
for (; length != 0; length--) SlReadByte();
}
size_t SlGetBytesRead(); size_t SlGetBytesRead();
size_t SlGetBytesWritten(); size_t SlGetBytesWritten();