Commit dc91b5f3 authored by deanm@chromium.org's avatar deanm@chromium.org

Avoid the KMP overhead for simple indexOf() operations. Will look into...

Avoid the KMP overhead for simple indexOf() operations.  Will look into evaluating the best cutoff between a simple search and KMP in the future.  This improves some simple operations ~1.5x.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@349 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6f536814
......@@ -911,12 +911,12 @@ static Object* Runtime_StringIndexOf(Arguments args) {
CONVERT_CHECKED(String, pat, args[1]);
Object* index = args[2];
int subject_length = sub->length();
int pattern_length = pat->length();
sub->TryFlatten();
pat->TryFlatten();
int subject_length = sub->length();
int pattern_length = pat->length();
uint32_t start_index;
if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
if (pattern_length == 0) return Smi::FromInt(start_index);
......@@ -934,8 +934,23 @@ static Object* Runtime_StringIndexOf(Arguments args) {
return Smi::FromInt(-1);
}
// For patterns with a length larger than one character we use the KMP
// algorithm.
// For small searches, KMP is not worth the setup overhead.
if (subject_length < 100) {
// We know our pattern is at least 2 characters, we cache the first so
// the common case of the first character not matching is faster.
uint16_t pattern_first_char = pat->Get(0);
for (int i = start_index; i + pattern_length <= subject_length; i++) {
if (sub->Get(i) != pattern_first_char) continue;
for (int j = 1; j < pattern_length; j++) {
if (pat->Get(j) != sub->Get(j + i)) break;
if (j == pattern_length - 1) return Smi::FromInt(i);
}
}
return Smi::FromInt(-1);
}
// For patterns with a larger length we use the KMP algorithm.
//
// Compute the 'next' table.
int* next_table = NewArray<int>(pattern_length);
......
......@@ -332,6 +332,7 @@ function ApplyReplacementFunction(replace, captures, subject) {
// ECMA-262 section 15.5.4.7
%AddProperty($String.prototype, "indexOf", function(searchString /* position */) { // length == 1
var str = ToString(this);
var str_len = str.length;
var searchStr = ToString(searchString);
var index = 0;
if (%_ArgumentsLength() > 1) {
......@@ -339,8 +340,8 @@ function ApplyReplacementFunction(replace, captures, subject) {
index = TO_INTEGER(arg1);
}
if (index < 0) index = 0;
if (index > str.length) index = str.length;
if (searchStr.length + index > str.length) return -1;
if (index > str_len) index = str_len;
if (searchStr.length + index > str_len) return -1;
return %StringIndexOf(str, searchStr, index);
}, DONT_ENUM);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment