Skip to content

Improve substring search performance for corner cases #11

Open
@bluss

Description

@bluss

I've subjected jetscii 0.3.1 to a benchmark suite of just a few pathological examples for substring search.

_jetscii benches very well_, there's just evidence of pathlogical cases

Result (may be noisy, i.e. individual benchmarks may be flukes)

  • find - str::find with &str pattern
  • rfind - str::rfind with &str pattern
  • jetscii_find str::find with Substring pattern
  • pcmp_find experimental function twsearch::pcmp::find, an incomplete, incorrect two-way search
  • regex_find using regex
test bad_naive::find                                      ... bench:         274 ns/iter (+/- 19) = 270 MB/s
test bad_naive::jetscii_find                              ... bench:         504 ns/iter (+/- 118) = 146 MB/s
test bad_naive::pcmp_find                                 ... bench:          96 ns/iter (+/- 1) = 770 MB/s
test bad_naive::regex_find                                ... bench:       1,077 ns/iter (+/- 89) = 68 MB/s
test bad_naive::rfind                                     ... bench:         231 ns/iter (+/- 16) = 320 MB/s
test bad_naive_reversed::find                             ... bench:         175 ns/iter (+/- 9) = 422 MB/s
test bad_naive_reversed::jetscii_find                     ... bench:          54 ns/iter (+/- 4) = 1370 MB/s
test bad_naive_reversed::pcmp_find                        ... bench:          43 ns/iter (+/- 4) = 1720 MB/s
test bad_naive_reversed::regex_find                       ... bench:          36 ns/iter (+/- 3) = 2055 MB/s
test bad_naive_reversed::rfind                            ... bench:         367 ns/iter (+/- 54) = 201 MB/s
test pathological_aa_100k::find                           ... bench:       3,084 ns/iter (+/- 149) = 32425 MB/s
test pathological_aa_100k::jetscii_find                   ... bench:      24,116 ns/iter (+/- 1,041) = 4146 MB/s
test pathological_aa_100k::pcmp_find                      ... bench:      27,241 ns/iter (+/- 2,031) = 3670 MB/s
test pathological_aa_100k::regex_find                     ... bench:       4,453 ns/iter (+/- 262) = 22456 MB/s
test pathological_aa_100k::rfind                          ... bench:       2,824 ns/iter (+/- 207) = 35410 MB/s
test pathological_aab_100k::find                          ... bench:     889,518 ns/iter (+/- 55,787) = 337 MB/s
test pathological_aab_100k::jetscii_find                  ... bench:     265,300 ns/iter (+/- 15,265) = 1130 MB/s
test pathological_aab_100k::pcmp_find                     ... bench:     183,135 ns/iter (+/- 11,808) = 1638 MB/s
test pathological_aab_100k::regex_find                    ... bench:   3,750,744 ns/iter (+/- 392,444) = 79 MB/s
test pathological_aab_100k::rfind                         ... bench:     859,327 ns/iter (+/- 104,678) = 348 MB/s
test pathological_two_way_10k::find                       ... bench:     107,896 ns/iter (+/- 48,497) = 278 MB/s
test pathological_two_way_10k::jetscii_find               ... bench:       7,406 ns/iter (+/- 1,072) = 4050 MB/s
test pathological_two_way_10k::pcmp_find                  ... bench:      19,444 ns/iter (+/- 22,302) = 1542 MB/s
test pathological_two_way_10k::regex_find                 ... bench:       1,329 ns/iter (+/- 2,413) = 22573 MB/s
test pathological_two_way_10k::rfind                      ... bench:       2,463 ns/iter (+/- 4,146) = 12180 MB/s
test pathological_two_way_20k::find                       ... bench:     305,465 ns/iter (+/- 505,176) = 327 MB/s
test pathological_two_way_20k::jetscii_find               ... bench:      25,179 ns/iter (+/- 39,142) = 3971 MB/s
test pathological_two_way_20k::pcmp_find                  ... bench:      64,983 ns/iter (+/- 113,250) = 1538 MB/s
test pathological_two_way_20k::regex_find                 ... bench:       6,175 ns/iter (+/- 12,215) = 16194 MB/s
test pathological_two_way_20k::rfind                      ... bench:       3,673 ns/iter (+/- 6,390) = 27225 MB/s
test pathological_two_way_20k_reversed::find              ... bench:       2,492 ns/iter (+/- 4,523) = 24077 MB/s
test pathological_two_way_20k_reversed::jetscii_find      ... bench:      45,084 ns/iter (+/- 80,989) = 1330 MB/s
test pathological_two_way_20k_reversed::pcmp_find         ... bench:      39,623 ns/iter (+/- 65,178) = 1514 MB/s
test pathological_two_way_20k_reversed::regex_find        ... bench:     406,637 ns/iter (+/- 730,079) = 147 MB/s
test pathological_two_way_20k_reversed::rfind             ... bench:     155,639 ns/iter (+/- 284,944) = 385 MB/s
test short_long::find                                     ... bench:       3,924 ns/iter (+/- 4,175) = 650 MB/s
test short_long::jetscii_find                             ... bench:         676 ns/iter (+/- 1,291) = 3773 MB/s
test short_long::pcmp_find                                ... bench:         810 ns/iter (+/- 1,531) = 3149 MB/s
test short_long::regex_find                               ... bench:       2,821 ns/iter (+/- 748) = 904 MB/s
test short_long::rfind                                    ... bench:       2,253 ns/iter (+/- 3,445) = 1132 MB/s
test short_short::find                                    ... bench:          68 ns/iter (+/- 119) = 823 MB/s
test short_short::jetscii_find                            ... bench:         109 ns/iter (+/- 127) = 513 MB/s
test short_short::pcmp_find                               ... bench:          43 ns/iter (+/- 69) = 1302 MB/s
test short_short::regex_find                              ... bench:          54 ns/iter (+/- 122) = 1037 MB/s
test short_short::rfind                                   ... bench:         125 ns/iter (+/- 160) = 448 MB/s

Conclusions:

  • jetscii 0.3.1 has algorithmic trouble, probably O(n²) problematics, see testcase bad_naive
  • Both jetscii and pcmp are losing to the byteset optimization in libstd's StrSearcher, see testcase pathological_aa_100k

Benchmark source, very messy crate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions