]> git.lizzy.rs Git - rust.git/commit
StrSearcher: Update substring search to use the Two Way algorithm
authorUlrik Sverdrup <root@localhost>
Sun, 14 Jun 2015 21:17:17 +0000 (23:17 +0200)
committerUlrik Sverdrup <root@localhost>
Sun, 21 Jun 2015 17:58:50 +0000 (19:58 +0200)
commitb890b7bbc732cd26f13c309573b5a3e45d0748de
tree36ab25e39ee5872b37b703aa1a8815006deb783a
parent9cc0b2247509d61d6a246a5c5ad67f84b9a2d8b6
StrSearcher: Update substring search to use the Two Way algorithm

To improve our substring search performance, revive the two way searcher
and adapt it to the Pattern API.

Fixes #25483, a performance bug: that particular case now completes faster
in optimized rust than in ruby (but they share the same order of magnitude).

Much thanks to @gereeter who helped me understand the reverse case
better and wrote the comment explaining `next_back` in the code.

I had quickcheck to fuzz test forward and reverse searching thoroughly.

The two way searcher implements both forward and reverse search,
but not double ended search. The forward and reverse parts of the two
way searcher are completely independent.

The two way searcher algorithm has very small, constant space overhead,
requiring no dynamic allocation. Our implementation is relatively fast,
especially due to the `byteset` addition to the algorithm, which speeds
up many no-match cases.

A bad case for the two way algorithm is:

```
let haystack = (0..10_000).map(|_| "dac").collect::<String>();
let needle = (0..100).map(|_| "bac").collect::<String>());
```

For this particular case, two way is not much faster than the naive
implementation it replaces.
src/libcollectionstest/str.rs
src/libcore/str/mod.rs
src/libcore/str/pattern.rs