From 3fc7c99d02f9ba3045a7f085bf8f74132c174b59 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Thu, 25 Jun 2020 00:50:49 -0700 Subject: 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(). --- libqpdf/BufferInputSource.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libqpdf/BufferInputSource.cc b/libqpdf/BufferInputSource.cc index cbb2e7f0..9e141510 100644 --- a/libqpdf/BufferInputSource.cc +++ b/libqpdf/BufferInputSource.cc @@ -61,14 +61,15 @@ BufferInputSource::findAndSkipNextEOL() } 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* end = buffer + end_pos; + unsigned char const* p = buffer + this->m->cur_offset; - void* start = const_cast(buffer) + this->m->cur_offset; - unsigned char* p1 = static_cast(memchr(start, '\r', len)); - unsigned char* p2 = static_cast(memchr(start, '\n', len)); - unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; - if (p) + while ((p < end) && !((*p == '\r') || (*p == '\n'))) + { + ++p; + } + if (p < end) { result = p - buffer; this->m->cur_offset = result + 1; -- cgit v1.2.3-54-g00ecf