2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-11-01 03:12:29 +00:00

Replace memchr with manual memory search

On large files with predominantly \n line endings, memchr(..'\r'..)
seems to waste a considerable amount of time searching for a line
ending candidate that we don't need.

On the Adobe PDF Reference Manual 1.7, this commit is 8x faster at
QPDF::processMemoryFile().
This commit is contained in:
James R. Barlow 2020-06-25 00:50:49 -07:00 committed by Jay Berkenbilt
parent 3221022fc9
commit 3fc7c99d02

View File

@ -61,14 +61,15 @@ BufferInputSource::findAndSkipNextEOL()
} }
qpdf_offset_t result = 0; qpdf_offset_t result = 0;
size_t len = QIntC::to_size(end_pos - this->m->cur_offset);
unsigned char const* buffer = this->m->buf->getBuffer(); unsigned char const* buffer = this->m->buf->getBuffer();
unsigned char const* end = buffer + end_pos;
unsigned char const* p = buffer + this->m->cur_offset;
void* start = const_cast<unsigned char*>(buffer) + this->m->cur_offset; while ((p < end) && !((*p == '\r') || (*p == '\n')))
unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len)); {
unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len)); ++p;
unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; }
if (p) if (p < end)
{ {
result = p - buffer; result = p - buffer;
this->m->cur_offset = result + 1; this->m->cur_offset = result + 1;