8000 Tighter inner loop; precompute the table · python/cpython@40d5217 · GitHub
[go: up one dir, main page]

Skip to content

Commit 40d5217

Browse files
committed
Tighter inner loop; precompute the table
1 parent fe9e9d9 commit 40d5217

File tree

1 file changed

+20
-37
lines changed

1 file changed

+20
-37
lines changed

Objects/stringlib/fastsearch.h

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,11 @@ STRINGLIB(_factorize)(const STRINGLIB_CHAR *needle,
288288
}
289289

290290
#define SHIFT_TYPE uint16_t
291-
#define NOT_FOUND ((1U<<(8*sizeof(SHIFT_TYPE))) - 1U)
292-
#define SHIFT_OVERFLOW (NOT_FOUND - 1U)
291+
#define MAX_SHIFT ((1U<<(8*sizeof(SHIFT_TYPE))) - 1U)
293292

294293
#define TABLE_SIZE_BITS 7
295-
#define TABLE_SIZE (1U << TABLE_SIZE_BITS)
296-
#define TABLE_MASK (TABLE_SIZE - 1U)
294+
#define TABLE_SIZE (1 << TABLE_SIZE_BITS)
295+
#define TABLE_MASK (TABLE_SIZE - 1)
297296

298297
typedef struct STRINGLIB(_pre) {
299298
const STRINGLIB_CHAR *needle;
@@ -316,17 +315,15 @@ STRINGLIB(_preprocess)(const STRINGLIB_CHAR *needle, Py_ssize_t len_needle,
316315
needle + p->period,
317316
p->cut * STRINGLIB_SIZEOF_CHAR));
318317
// Now fill up a table
319-
memset(&(p->table[0]), 0xff, TABLE_SIZE*sizeof(SHIFT_TYPE));
320-
assert(p->table[0] == NOT_FOUND);
321-
assert(p->table[TABLE_MASK] == NOT_FOUND);
318+
SHIFT_TYPE default_shift = Py_SAFE_DOWNCAST(Py_MIN(len_needle, MAX_SHIFT),
319+
Py_ssize_t, SHIFT_TYPE);
320+
for (int i = 0; i < TABLE_SIZE; i++) {
321+
p->table[i] = default_shift;
322+
}
322323
for (Py_ssize_t i = 0; i < len_needle; i++) {
323-
Py_ssize_t shift = len_needle - i;
324-
if (shift > SHIFT_OVERFLOW) {
325-
shift = SHIFT_OVERFLOW;
326-
}
327-
p->table[needle[i] & TABLE_MASK] = Py_SAFE_DOWNCAST(shift,
328-
Py_ssize_t,
329-
SHIFT_TYPE);
324+
Py_ssize_t shift = Py_MIN(MAX_SHIFT, len_needle - i);
325+
int index = needle[i] & TABLE_MASK;
326+
p->table[index] = Py_SAFE_DOWNCAST(shift, Py_ssize_t, SHIFT_TYPE);
330327
}
331328
}
332329

@@ -342,6 +339,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
342339
const STRINGLIB_CHAR *needle = p->needle;
343340
const STRINGLIB_CHAR *window = haystack;
344341
const STRINGLIB_CHAR *last_window = haystack + len_haystack - len_needle;
342+
SHIFT_TYPE *table = p->table;
345343
LOG("===== Two-way: \"%s\" in \"%s\". =====\n", needle, haystack);
346344

347345
if (p->is_periodic) {
@@ -362,16 +360,9 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
362360
// as well jump to line up the character *after* the
363361
// current window.
364362
STRINGLIB_CHAR first_outside = window[len_needle];
365-
SHIFT_TYPE shift = p->table[first_outside & TABLE_MASK];
366-
if (shift == NOT_FOUND) {
367-
LOG("\"%c\" not found. Skipping entirely.\n",
368-
first_outside);
369-
window += len_needle + 1;
370-
}
371-
else {
372-
LOG("Shifting to line up \"%c\".\n", first_outside);
373-
window += shift;
374-
}
363+
SHIFT_TYPE shift = table[first_outside & TABLE_MASK];
364+
LOG("Shifting to line up \"%c\".\n", first_outside);
365+
window += shift;
375366
memory = 0;
376367
continue;
377368
}
@@ -423,16 +414,9 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
423414
// as well jump to line up the character *after* the
424415
// current window.
425416
STRINGLIB_CHAR first_outside = window[len_needle];
426-
SHIFT_TYPE shift = p->table[first_outside & TABLE_MASK];
427-
if (shift == NOT_FOUND) {
428-
LOG("\"%c\" not found. Skipping entirely.\n",
429-
first_outside);
430-
window += len_needle + 1;
431-
}
432-
else {
433-
LOG("Shifting to line up \"%c\".\n", first_outside);
434-
window += shift;
435-
}
417+
SHIFT_TYPE shift = table[first_outside & TABLE_MASK];
418+
LOG("Shifting to line up \"%c\".\n", first_outside);
419+
window += shift;
436420
continue;
437421
}
438422

@@ -544,8 +528,7 @@ STRINGLIB(_two_way_count)(const STRINGLIB_CHAR *haystack,
544528
}
545529

546530
#undef SHIFT_TYPE
547-
#undef NOT_FOUND
548-
#undef SHIFT_OVERFLOW
531+
#undef MAX_SHIFT
549532
#undef TABLE_SIZE_BITS
550533
#undef TABLE_SIZE
551534
#undef TABLE_MASK
@@ -588,7 +571,7 @@ FASTSEARCH(const STRINGLIB_CHAR* s, Py_ssize_t n,
588571
}
589572

590573
mlast = m - 1;
591-
skip = mlast - 1;
574+
skip = mlast;
592575
mask = 0;
593576

594577
if (mode != FAST_RSEARCH) {

0 commit comments

Comments
 (0)
0