From e3cdaab49ebceac684dc6043dc89e1ce339a4f5f Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Wed, 4 Mar 2015 15:16:59 -0700 Subject: [PATCH] buffer: make indexOf faster Improve the performance of IndexOf() for Buffer#indexOf() searches. --- src/node_buffer.cc | 36 +++++++++++++++++++++++----- test/parallel/test-buffer-indexof.js | 1 + 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 2d00ca97cc0f58..bc8c7cba5b0724 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -607,13 +607,37 @@ int32_t IndexOf(const char* haystack, const char* needle, size_t n_length) { CHECK_GE(h_length, n_length); - // TODO(trevnorris): Implement Boyer-Moore string search algorithm. - for (size_t i = 0; i < h_length - n_length + 1; i++) { - if (haystack[i] == needle[0]) { - if (memcmp(haystack + i, needle, n_length) == 0) - return i; - } + + const char* inc; + const void* ptr; + + // Guard against zero length searches + if (h_length == 0 || n_length == 0 || n_length > h_length) + return -1; + + // Single character case + if (n_length == 1) { + ptr = memchr(haystack, *needle, h_length); + if (ptr == nullptr) + return -1; + return static_cast(static_cast(ptr) - haystack); } + + // Do multicharacter string match + inc = haystack; + do { + ptr = memchr(inc, *needle, h_length - static_cast(inc - haystack)); + if (ptr != nullptr) { + const void* ptr2 = memmem(inc, + h_length - static_cast(inc - haystack), + needle, + n_length); + if (ptr2 != nullptr) + return static_cast(static_cast(ptr2) - haystack); + inc = static_cast(ptr); + } + } while (ptr != nullptr); + return -1; } diff --git a/test/parallel/test-buffer-indexof.js b/test/parallel/test-buffer-indexof.js index 32748dcaaab727..daae45a4f6bf2b 100644 --- a/test/parallel/test-buffer-indexof.js +++ b/test/parallel/test-buffer-indexof.js @@ -26,6 +26,7 @@ assert.equal(b.indexOf('bc', -5), 1); assert.equal(b.indexOf('bc', NaN), 1); assert.equal(b.indexOf('bc', -Infinity), 1); assert.equal(b.indexOf('bc', Infinity), -1); +assert.equal(b.indexOf('cd'), 2); assert.equal(b.indexOf('f'), b.length - 1); assert.equal(b.indexOf('z'), -1); assert.equal(b.indexOf(''), -1);