Commit 3fc7c99d02f9ba3045a7f085bf8f74132c174b59
Committed by
Jay Berkenbilt
1 parent
3221022f
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().
Showing
1 changed file
with
7 additions
and
6 deletions
libqpdf/BufferInputSource.cc
| ... | ... | @@ -61,14 +61,15 @@ BufferInputSource::findAndSkipNextEOL() |
| 61 | 61 | } |
| 62 | 62 | |
| 63 | 63 | qpdf_offset_t result = 0; |
| 64 | - size_t len = QIntC::to_size(end_pos - this->m->cur_offset); | |
| 65 | 64 | unsigned char const* buffer = this->m->buf->getBuffer(); |
| 65 | + unsigned char const* end = buffer + end_pos; | |
| 66 | + unsigned char const* p = buffer + this->m->cur_offset; | |
| 66 | 67 | |
| 67 | - void* start = const_cast<unsigned char*>(buffer) + this->m->cur_offset; | |
| 68 | - unsigned char* p1 = static_cast<unsigned char*>(memchr(start, '\r', len)); | |
| 69 | - unsigned char* p2 = static_cast<unsigned char*>(memchr(start, '\n', len)); | |
| 70 | - unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2; | |
| 71 | - if (p) | |
| 68 | + while ((p < end) && !((*p == '\r') || (*p == '\n'))) | |
| 69 | + { | |
| 70 | + ++p; | |
| 71 | + } | |
| 72 | + if (p < end) | |
| 72 | 73 | { |
| 73 | 74 | result = p - buffer; |
| 74 | 75 | this->m->cur_offset = result + 1; | ... | ... |