Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for C++ std::regex to benchmarks #459

Closed
wants to merge 3 commits into from

Conversation

mkrupcale
Copy link
Contributor

Detailed changes

  • bench/Cargo.toml: add re-stdcpp feature
  • bench/build.rs: add cstdcpp library to bench build
  • bench/compile: add re-stdcpp feature to bench compile script
  • bench/run: add re-stdcpp feature to bench run script
  • bench/src/bench.rs: use ffi::stdcpp::Regex, define its text! macro, and Text type
  • bench/src/ffi/mod.rs: declare stdcpp module
  • bench/src/ffi/stdcpp.cpp: implement C API using C++ std::regex
  • bench/src/ffi/stdcpp.rs: Rust Regex API implementation using C++ std::regex C API wrapper
  • bench/src/main.rs: add stdcpp to bench main
  • bench/src/misc.rs:
    • do not run no_exponential benchmark for re-stdcpp feature because libstdc++ std::regex implementation currently seems to have exponential behavior here
    • do not run match_class_unicode benchmark for re-stdcpp feature because std::regex ECMAScript grammar does not support unicode character classes
  • bench/src/sherlock.rs:
    • do not run name_sherlock_nocase, name_holmes_nocase, name_sherlock_holmes_nocase, name_alt3_nocase, name_alt4_nocase, name_alt5_nocase, the_nocase, everything_greedy_nl, and line_boundary_sherlock_holmes benchmarks for re-stdcpp feature because std::regex ECMAScript grammar does not support inline modifier syntax
    • do not run letters, letters_upper, and letters_lower benchmarks for re-stdcpp feature because std::regex ECMAScript grammar does not support unicode character classes
    • use a different regex for everything_greedy benchmark because std::regex '.' does not match '\r'
    • words benchmark for std::regex matches RE2 test result, so use that test for re-stdcpp feature as well
    • do not run holmes_coword_watson benchmark for re-stdcpp feature because libstdc++ std::regex implementation currently seems to have exponential behavior here

Results

Unfortunately, the libstdc++ std::regex implementation (version 7.3.1) on my machine did not do too well, often being tens or hundreds of times slower than PCRE2 or RE2. Some example results for libstdc++ are shown here:

running 81 tests
test misc::anchored_literal_long_match      ... bench:         326 ns/iter (+/- 0) = 1196 MB/s
test misc::anchored_literal_long_non_match  ... bench:      14,983 ns/iter (+/- 13) = 26 MB/s
test misc::anchored_literal_short_match     ... bench:         316 ns/iter (+/- 1) = 82 MB/s
test misc::anchored_literal_short_non_match ... bench:       1,186 ns/iter (+/- 1) = 21 MB/s
test misc::easy0_1K                         ... bench:      39,988 ns/iter (+/- 72) = 26 MB/s
test misc::easy0_1MB                        ... bench:  40,376,744 ns/iter (+/- 30,603) = 25 MB/s
test misc::easy0_32                         ... bench:       1,794 ns/iter (+/- 2) = 32 MB/s
test misc::easy0_32K                        ... bench:   1,262,276 ns/iter (+/- 1,227) = 25 MB/s
test misc::easy1_1K                         ... bench:      39,959 ns/iter (+/- 48) = 26 MB/s
test misc::easy1_1MB                        ... bench:  40,379,174 ns/iter (+/- 27,276) = 25 MB/s
test misc::easy1_32                         ... bench:       1,833 ns/iter (+/- 1) = 28 MB/s
test misc::easy1_32K                        ... bench:   1,262,166 ns/iter (+/- 1,186) = 25 MB/s
test misc::hard_1K                          ... bench:     999,561 ns/iter (+/- 16,814) = 1 MB/s
test misc::hard_1MB                         ... bench: 1,059,059,453 ns/iter (+/- 5,881,158)
test misc::hard_32                          ... bench:      30,532 ns/iter (+/- 493) = 1 MB/s
test misc::hard_32K                         ... bench:  34,627,995 ns/iter (+/- 490,957)
test misc::literal                          ... bench:       2,146 ns/iter (+/- 1) = 23 MB/s
test misc::long_needle1                     ... bench:  29,212,899 ns/iter (+/- 12,436) = 3 MB/s
test misc::long_needle2                     ... bench:  29,231,653 ns/iter (+/- 17,311) = 3 MB/s
test misc::match_class                      ... bench:       3,404 ns/iter (+/- 3) = 23 MB/s
test misc::match_class_in_range             ... bench:       3,399 ns/iter (+/- 3) = 23 MB/s
test misc::medium_1K                        ... bench:      41,221 ns/iter (+/- 107) = 25 MB/s
test misc::medium_1MB                       ... bench:  41,618,788 ns/iter (+/- 24,107) = 25 MB/s
test misc::medium_32                        ... bench:       1,862 ns/iter (+/- 2) = 32 MB/s
test misc::medium_32K                       ... bench:   1,300,733 ns/iter (+/- 1,304) = 25 MB/s
test misc::not_literal                      ... bench:       2,888 ns/iter (+/- 11) = 17 MB/s
test misc::one_pass_long_prefix             ... bench:         571 ns/iter (+/- 3) = 45 MB/s
test misc::one_pass_long_prefix_not         ... bench:         580 ns/iter (+/- 0) = 44 MB/s
test misc::one_pass_short                   ... bench:       1,733 ns/iter (+/- 37) = 9 MB/s
test misc::one_pass_short_not               ... bench:       1,717 ns/iter (+/- 50) = 9 MB/s
test misc::reallyhard2_1K                   ... bench:     996,324 ns/iter (+/- 45,664) = 1 MB/s
test misc::reallyhard_1K                    ... bench:   1,012,203 ns/iter (+/- 1,485) = 1 MB/s
test misc::reallyhard_1MB                   ... bench: 1,053,934,632 ns/iter (+/- 4,977,685)
test misc::reallyhard_32                    ... bench:      30,234 ns/iter (+/- 464) = 1 MB/s
test misc::reallyhard_32K                   ... bench:  34,378,406 ns/iter (+/- 487,743)
test misc::reverse_suffix_no_quadratic      ... bench:     331,368 ns/iter (+/- 434) = 24 MB/s
test regexdna::find_new_lines               ... bench: 307,181,237 ns/iter (+/- 78,961) = 16 MB/s
test regexdna::subst1                       ... bench: 201,886,931 ns/iter (+/- 97,655) = 25 MB/s
test regexdna::subst10                      ... bench: 207,618,870 ns/iter (+/- 178,302) = 24 MB/s
test regexdna::subst11                      ... bench: 201,880,614 ns/iter (+/- 116,389) = 25 MB/s
test regexdna::subst2                       ... bench: 201,861,384 ns/iter (+/- 125,616) = 25 MB/s
test regexdna::subst3                       ... bench: 207,640,785 ns/iter (+/- 268,453) = 24 MB/s
test regexdna::subst4                       ... bench: 201,919,815 ns/iter (+/- 114,920) = 25 MB/s
test regexdna::subst5                       ... bench: 201,899,802 ns/iter (+/- 108,025) = 25 MB/s
test regexdna::subst6                       ... bench: 201,878,177 ns/iter (+/- 204,125) = 25 MB/s
test regexdna::subst7                       ... bench: 201,941,772 ns/iter (+/- 523,708) = 25 MB/s
test regexdna::subst8                       ... bench: 201,896,316 ns/iter (+/- 135,968) = 25 MB/s
test regexdna::subst9                       ... bench: 201,911,005 ns/iter (+/- 196,632) = 25 MB/s
test regexdna::variant1                     ... bench: 336,160,741 ns/iter (+/- 257,036) = 15 MB/s
test regexdna::variant2                     ... bench: 392,650,258 ns/iter (+/- 2,880,460) = 12 MB/s
test regexdna::variant3                     ... bench: 351,431,623 ns/iter (+/- 285,862) = 14 MB/s
test regexdna::variant4                     ... bench: 338,043,444 ns/iter (+/- 91,547,961) = 15 MB/s
test regexdna::variant5                     ... bench: 334,627,689 ns/iter (+/- 264,418) = 15 MB/s
test regexdna::variant6                     ... bench: 336,059,615 ns/iter (+/- 5,423,345) = 15 MB/s
test regexdna::variant7                     ... bench: 338,298,685 ns/iter (+/- 523,873) = 15 MB/s
test regexdna::variant8                     ... bench: 348,758,502 ns/iter (+/- 258,051) = 14 MB/s
test regexdna::variant9                     ... bench: 401,088,309 ns/iter (+/- 482,367) = 12 MB/s
test sherlock::before_after_holmes          ... bench: 103,667,977 ns/iter (+/- 205,097) = 5 MB/s
test sherlock::before_holmes                ... bench: 103,809,888 ns/iter (+/- 209,549) = 5 MB/s
test sherlock::everything_greedy            ... bench:  30,140,710 ns/iter (+/- 121,690) = 19 MB/s
test sherlock::holmes_cochar_watson         ... bench:  34,338,985 ns/iter (+/- 33,550) = 17 MB/s
test sherlock::ing_suffix                   ... bench:  83,871,295 ns/iter (+/- 153,065) = 7 MB/s
test sherlock::ing_suffix_limited_space     ... bench:  48,593,384 ns/iter (+/- 43,535) = 12 MB/s
test sherlock::name_alt1                    ... bench:  33,965,251 ns/iter (+/- 25,075) = 17 MB/s
test sherlock::name_alt2                    ... bench:  34,131,786 ns/iter (+/- 27,935) = 17 MB/s
test sherlock::name_alt3                    ... bench:  74,160,916 ns/iter (+/- 29,644) = 8 MB/s
test sherlock::name_alt4                    ... bench:  34,333,961 ns/iter (+/- 26,138) = 17 MB/s
test sherlock::name_alt5                    ... bench:  41,481,282 ns/iter (+/- 32,529) = 14 MB/s
test sherlock::name_holmes                  ... bench:  22,940,321 ns/iter (+/- 16,953) = 25 MB/s
test sherlock::name_sherlock                ... bench:  22,915,858 ns/iter (+/- 22,849) = 25 MB/s
test sherlock::name_sherlock_holmes         ... bench:  22,899,246 ns/iter (+/- 23,669) = 25 MB/s
test sherlock::name_whitespace              ... bench:  22,901,419 ns/iter (+/- 18,870) = 25 MB/s
test sherlock::no_match_common              ... bench:  23,403,282 ns/iter (+/- 20,850) = 25 MB/s
test sherlock::no_match_really_common       ... bench:  23,404,467 ns/iter (+/- 28,693) = 25 MB/s
test sherlock::no_match_uncommon            ... bench:  22,917,887 ns/iter (+/- 27,731) = 25 MB/s
test sherlock::quotes                       ... bench:  29,375,307 ns/iter (+/- 60,734) = 20 MB/s
test sherlock::repeated_class_negation      ... bench:  53,412,556 ns/iter (+/- 28,818) = 11 MB/s
test sherlock::the_lower                    ... bench:  26,024,165 ns/iter (+/- 33,233) = 22 MB/s
test sherlock::the_upper                    ... bench:  23,689,507 ns/iter (+/- 21,524) = 25 MB/s
test sherlock::the_whitespace               ... bench:  24,354,227 ns/iter (+/- 30,471) = 24 MB/s
test sherlock::word_ending_n                ... bench: 163,437,469 ns/iter (+/- 157,966) = 3 MB/s

test result: ok. 0 passed; 0 failed; 0 ignored; 81 measured; 0 filtered out

* bench/Cargo.toml: add `re-stdcpp` feature
* bench/build.rs: add `cstdcpp` library to bench build
* bench/compile: add `re-stdcpp` feature to bench compile script
* bench/run: add `re-stdcpp` feature to bench run script
* bench/src/bench.rs: use `ffi::stdcpp::Regex`, define its `text!` macro, and `Text` type
* bench/src/ffi/mod.rs: declare `stdcpp` module
* bench/src/ffi/stdcpp.cpp: implement C API using C++ `std::regex`
* bench/src/ffi/stdcpp.rs: Rust `Regex` API implementation using C++ `std::regex` C API wrapper
* bench/src/main.rs: add stdcpp to bench main
* bench/src/misc.rs:
   - do not run `no_exponential` benchmark for `re-stdcpp` feature because `libstdc++` `std::regex` implementation currently seems to have exponential behavior here
   - do not run `match_class_unicode` benchmark for `re-stdcpp` feature because `std::regex` ECMAScript grammar does not support unicode character classes
* bench/src/sherlock.rs:
   - do not run `name_sherlock_nocase`, `name_holmes_nocase`, `name_sherlock_holmes_nocase`, `name_alt3_nocase`, `name_alt4_nocase`, `name_alt5_nocase`, `the_nocase`, `everything_greedy_nl`, and `line_boundary_sherlock_holmes` benchmarks for `re-stdcpp` feature because `std::regex` ECMAScript grammar does not support inline modifier syntax
   - do not run `letters`, `letters_upper`, and `letters_lower` benchmarks for `re-stdcpp` feature because `std::regex` ECMAScript grammar does not support unicode character classes
   - use a different regex for `everything_greedy` benchmark because `std::regex` '.' does not match '\r'
   - `words` benchmark for `std::regex` matches RE2 test result, so use that test for `re-stdcpp` feature as well
   - do not run `holmes_coword_watson` benchmark for `re-stdcpp` feature because `libstdc++` `std::regex` implementation currently seems to have exponential behavior here
@BurntSushi
Copy link
Member

This is amazing! Thanks so much for doing this. I am also surprised at how slow std::regex is. Like, it's really bad. Here's a comparison with Rust:

 name                                    bench.stdcpp ns/iter   bench.rust ns/iter     diff ns/iter    diff %       speedup
 misc::anchored_literal_long_match       163 (2392 MB/s)        19 (20526 MB/s)                -144   -88.34%        x 8.58
 misc::anchored_literal_long_non_match   6,066 (64 MB/s)        22 (17727 MB/s)              -6,044   -99.64%      x 275.73
 misc::anchored_literal_short_match      160 (162 MB/s)         19 (1368 MB/s)                 -141   -88.12%        x 8.42
 misc::anchored_literal_short_non_match  496 (52 MB/s)          23 (1130 MB/s)                 -473   -95.36%       x 21.57
 misc::easy0_1K                          15,564 (67 MB/s)       18 (58388 MB/s)             -15,546   -99.88%      x 864.67
 misc::easy0_1MB                         15,636,176 (67 MB/s)   21 (49933476 MB/s)      -15,636,155  -100.00%   x 744579.81
 misc::easy0_32                          784 (75 MB/s)          18 (3277 MB/s)                 -766   -97.70%       x 43.56
 misc::easy0_32K                         485,866 (67 MB/s)      19 (1726052 MB/s)          -485,847  -100.00%    x 25571.89
 misc::easy1_1K                          15,756 (66 MB/s)       44 (23727 MB/s)             -15,712   -99.72%      x 358.09
 misc::easy1_1MB                         16,351,704 (64 MB/s)   46 (22795565 MB/s)      -16,351,658  -100.00%   x 355471.83
 misc::easy1_32                          789 (65 MB/s)          43 (1209 MB/s)                 -746   -94.55%       x 18.35
 misc::easy1_32K                         485,444 (67 MB/s)      43 (762511 MB/s)           -485,401   -99.99%    x 11289.40
 misc::hard_1K                           324,370 (3 MB/s)       55 (19109 MB/s)            -324,315   -99.98%     x 5897.64
 misc::hard_1MB                          352,577,333 (2 MB/s)   58 (18079362 MB/s)     -352,577,275  -100.00%  x 6078919.53
 misc::hard_32                           10,281 (5 MB/s)        55 (1072 MB/s)              -10,226   -99.47%      x 186.93
 misc::hard_32K                          10,976,988 (2 MB/s)    55 (596272 MB/s)        -10,976,933  -100.00%   x 199581.60
 misc::literal                           878 (58 MB/s)          14 (3642 MB/s)                 -864   -98.41%       x 62.71
 misc::long_needle1                      17,358,871 (5 MB/s)    1,335 (74907 MB/s)      -17,357,536   -99.99%    x 13002.90
 misc::long_needle2                      17,456,703 (5 MB/s)    558,971 (178 MB/s)      -16,897,732   -96.80%       x 31.23
 misc::match_class                       1,367 (59 MB/s)        66 (1227 MB/s)               -1,301   -95.17%       x 20.71
 misc::match_class_in_range              1,377 (58 MB/s)        28 (2892 MB/s)               -1,349   -97.97%       x 49.18
 misc::medium_1K                         16,603 (63 MB/s)       17 (61882 MB/s)             -16,586   -99.90%      x 976.65
 misc::medium_1MB                        16,258,701 (64 MB/s)   20 (52430200 MB/s)      -16,258,681  -100.00%   x 812935.05
 misc::medium_32                         788 (76 MB/s)          17 (3529 MB/s)                 -771   -97.84%       x 46.35
 misc::medium_32K                        504,476 (65 MB/s)      17 (1929176 MB/s)          -504,459  -100.00%    x 29675.06
 misc::not_literal                       1,119 (45 MB/s)        93 (548 MB/s)                -1,026   -91.69%       x 12.03
 misc::one_pass_long_prefix              286 (90 MB/s)          52 (500 MB/s)                  -234   -81.82%        x 5.50
 misc::one_pass_long_prefix_not          284 (91 MB/s)          52 (500 MB/s)                  -232   -81.69%        x 5.46
 misc::one_pass_short                    538 (31 MB/s)          39 (435 MB/s)                  -499   -92.75%       x 13.79
 misc::one_pass_short_not                533 (31 MB/s)          43 (395 MB/s)                  -490   -91.93%       x 12.40
 misc::reallyhard2_1K                    349,094 (2 MB/s)       60 (17333 MB/s)            -349,034   -99.98%     x 5818.23
 misc::reallyhard_1K                     331,840 (3 MB/s)       1,611 (652 MB/s)           -330,229   -99.51%      x 205.98
 misc::reallyhard_1MB                    354,754,782 (2 MB/s)   1,613,666 (649 MB/s)   -353,141,116   -99.55%      x 219.84
 misc::reallyhard_32                     11,758 (5 MB/s)        104 (567 MB/s)              -11,654   -99.12%      x 113.06
 misc::reallyhard_32K                    11,271,519 (2 MB/s)    49,402 (663 MB/s)       -11,222,117   -99.56%      x 228.16
 misc::reverse_suffix_no_quadratic       125,915 (63 MB/s)      4,083 (1959 MB/s)          -121,832   -96.76%       x 30.84
 regexdna::find_new_lines                137,411,083 (36 MB/s)  13,375,464 (380 MB/s)  -124,035,619   -90.27%       x 10.27
 regexdna::subst1                        80,234,896 (63 MB/s)   751,206 (6766 MB/s)     -79,483,690   -99.06%      x 106.81
 regexdna::subst10                       80,048,143 (63 MB/s)   750,451 (6773 MB/s)     -79,297,692   -99.06%      x 106.67
 regexdna::subst11                       80,495,627 (63 MB/s)   749,816 (6779 MB/s)     -79,745,811   -99.07%      x 107.35
 regexdna::subst2                        79,807,823 (63 MB/s)   747,166 (6803 MB/s)     -79,060,657   -99.06%      x 106.81
 regexdna::subst3                        79,845,617 (63 MB/s)   752,136 (6758 MB/s)     -79,093,481   -99.06%      x 106.16
 regexdna::subst4                        82,220,582 (61 MB/s)   745,284 (6820 MB/s)     -81,475,298   -99.09%      x 110.32
 regexdna::subst5                        85,482,880 (59 MB/s)   774,567 (6562 MB/s)     -84,708,313   -99.09%      x 110.36
 regexdna::subst6                        81,045,018 (62 MB/s)   782,318 (6497 MB/s)     -80,262,700   -99.03%      x 103.60
 regexdna::subst7                        80,030,411 (63 MB/s)   761,968 (6671 MB/s)     -79,268,443   -99.05%      x 105.03
 regexdna::subst8                        80,288,689 (63 MB/s)   759,450 (6693 MB/s)     -79,529,239   -99.05%      x 105.72
 regexdna::subst9                        80,352,045 (63 MB/s)   847,412 (5998 MB/s)     -79,504,633   -98.95%       x 94.82
 regexdna::variant1                      151,449,122 (33 MB/s)  3,016,041 (1685 MB/s)  -148,433,081   -98.01%       x 50.21
 regexdna::variant2                      169,584,648 (29 MB/s)  5,984,865 (849 MB/s)   -163,599,783   -96.47%       x 28.34
 regexdna::variant3                      157,321,828 (32 MB/s)  6,896,393 (737 MB/s)   -150,425,435   -95.62%       x 22.81
 regexdna::variant4                      152,059,107 (33 MB/s)  6,973,960 (728 MB/s)   -145,085,147   -95.41%       x 21.80
 regexdna::variant5                      151,862,787 (33 MB/s)  5,611,820 (905 MB/s)   -146,250,967   -96.30%       x 27.06
 regexdna::variant6                      151,669,000 (33 MB/s)  5,664,164 (897 MB/s)   -146,004,836   -96.27%       x 26.78
 regexdna::variant7                      153,307,182 (33 MB/s)  4,935,872 (1029 MB/s)  -148,371,310   -96.78%       x 31.06
 regexdna::variant8                      156,369,389 (32 MB/s)  4,990,988 (1018 MB/s)  -151,378,401   -96.81%       x 31.33
 regexdna::variant9                      165,144,360 (30 MB/s)  4,892,748 (1038 MB/s)  -160,251,612   -97.04%       x 33.75
 sherlock::before_after_holmes           41,140,549 (14 MB/s)   908,149 (655 MB/s)      -40,232,400   -97.79%       x 45.30
 sherlock::before_holmes                 40,915,245 (14 MB/s)   62,578 (9507 MB/s)      -40,852,667   -99.85%      x 653.83
 sherlock::everything_greedy             10,226,344 (58 MB/s)   1,969,729 (302 MB/s)     -8,256,615   -80.74%        x 5.19
 sherlock::holmes_cochar_watson          13,918,389 (42 MB/s)   102,879 (5782 MB/s)     -13,815,510   -99.26%      x 135.29
 sherlock::ing_suffix                    33,275,307 (17 MB/s)   389,050 (1529 MB/s)     -32,886,257   -98.83%       x 85.53
 sherlock::ing_suffix_limited_space      20,220,146 (29 MB/s)   1,084,290 (548 MB/s)    -19,135,856   -94.64%       x 18.65
 sherlock::name_alt1                     13,734,351 (43 MB/s)   27,853 (21359 MB/s)     -13,706,498   -99.80%      x 493.10
 sherlock::name_alt2                     13,763,518 (43 MB/s)   83,674 (7110 MB/s)      -13,679,844   -99.39%      x 164.49
 sherlock::name_alt3                     37,088,050 (16 MB/s)   92,270 (6447 MB/s)      -36,995,780   -99.75%      x 401.95
 sherlock::name_alt4                     13,783,834 (43 MB/s)   121,199 (4908 MB/s)     -13,662,635   -99.12%      x 113.73
 sherlock::name_alt5                     18,338,767 (32 MB/s)   85,101 (6990 MB/s)      -18,253,666   -99.54%      x 215.49
 sherlock::name_holmes                   9,002,045 (66 MB/s)    32,056 (18559 MB/s)      -8,969,989   -99.64%      x 280.82
 sherlock::name_sherlock                 9,006,566 (66 MB/s)    55,932 (10636 MB/s)      -8,950,634   -99.38%      x 161.03
 sherlock::name_sherlock_holmes          10,184,244 (58 MB/s)   23,682 (25121 MB/s)     -10,160,562   -99.77%      x 430.04
 sherlock::name_whitespace               10,187,356 (58 MB/s)   64,625 (9205 MB/s)      -10,122,731   -99.37%      x 157.64
 sherlock::no_match_common               10,680,009 (55 MB/s)   14,898 (39933 MB/s)     -10,665,111   -99.86%      x 716.88
 sherlock::no_match_really_common        10,693,041 (55 MB/s)   287,953 (2066 MB/s)     -10,405,088   -97.31%       x 37.13
 sherlock::no_match_uncommon             10,157,212 (58 MB/s)   14,978 (39720 MB/s)     -10,142,234   -99.85%      x 678.14
 sherlock::quotes                        12,704,941 (46 MB/s)   484,337 (1228 MB/s)     -12,220,604   -96.19%       x 26.23
 sherlock::repeated_class_negation       31,365,801 (18 MB/s)   86,001,951 (6 MB/s)      54,636,150   174.19%        x 0.36
 sherlock::the_lower                     11,561,785 (51 MB/s)   508,855 (1169 MB/s)     -11,052,930   -95.60%       x 22.72
 sherlock::the_upper                     10,305,141 (57 MB/s)   34,184 (17403 MB/s)     -10,270,957   -99.67%      x 301.46
 sherlock::the_whitespace                12,576,498 (47 MB/s)   989,405 (601 MB/s)      -11,587,093   -92.13%       x 12.71
 sherlock::word_ending_n                 84,959,790 (7 MB/s)    1,679,593 (354 MB/s)    -83,280,197   -98.02%       x 50.58

@BurntSushi
Copy link
Member

I'm not a C++ expert, but I can't spot any obvious deficiencies in your bindings either. e.g., I don't see any extra allocations going on.

@mkrupcale
Copy link
Contributor Author

Yeah, I was pretty surprised by the results as well. The implementation here follows the RE2 one fairly closely, obviously adjusted to use the std::regex API, so I think at least those two implementations should be comparable. On the other hand, I wasn't sure how much overhead there was between the Rust native implementation and the FFI implementations, especially considering the use of unsafe blocks for the FFI implementations.

I would also like to try using LLVM/Clang when building to test the libc++ implementation of std::regex, and test Boost.Regex, which has more or less the same API as std::regex.

@BurntSushi
Copy link
Member

On the other hand, I wasn't sure how much overhead there was between the Rust native implementation and the FFI implementations, especially considering the use of unsafe blocks for the FFI implementations.

The only overhead is probably a function call. One possibility would be to implement the iterator inside the glue code, which might give you inlining. However, this will likely only help in benchmarks that have a ton of matches. (Most don't.)

Benchmarking against Clang probably won't show too much of a difference, especially with these speeds. Benchmarking Boost is a good idea though! :-)

* bench/Cargo.toml: add `libcxx` feature
* bench/build.rs: link against `libc++` when `libcxx` feature is specified with `re-stdcpp` feature. The `cc::Build::cpp_set_stdlib("c++")` method is not used because GCC does not support the `-stdlib` flag.
* bench/run: add `stdcpp-libcxx` option for benchmarking `libc++` `std::regex` implementation.

This requires the user to specify the compiler `CXX` and compiler flags `CXXFLAGS` necessary for compiling with `libc++`[1].

[1] https://libcxx.llvm.org/docs/UsingLibcxx.html
@mkrupcale
Copy link
Contributor Author

I've added support for linking against the libc++ implementation of std::regex. It can be used[1] with either Clang or GCC. The results seem to indicate that libc++ on my machine (version 5.0.1) is often about 25%-50% the speed of libstdc++ (version 7.3.1), which does not bode well for either of these C++ std::regex implementations:

 name                                    stdcpp.bench ns/iter   stdcpp-libcxx.bench ns/iter   diff ns/iter   diff %  speedup 
 misc::anchored_literal_long_match       326 (1196 MB/s)        358 (1089 MB/s)                         32    9.82%   x 0.91 
 misc::anchored_literal_long_non_match   14,983 (26 MB/s)       47,884 (8 MB/s)                     32,901  219.59%   x 0.31 
 misc::anchored_literal_short_match      316 (82 MB/s)          354 (73 MB/s)                           38   12.03%   x 0.89 
 misc::anchored_literal_short_non_match  1,186 (21 MB/s)        3,258 (7 MB/s)                       2,072  174.70%   x 0.36 
 misc::easy0_1K                          39,988 (26 MB/s)       86,588 (12 MB/s)                    46,600  116.53%   x 0.46 
 misc::easy0_1MB                         40,376,744 (25 MB/s)   89,171,234 (11 MB/s)            48,794,490  120.85%   x 0.45 
 misc::easy0_32                          1,794 (32 MB/s)        3,045 (19 MB/s)                      1,251   69.73%   x 0.59 
 misc::easy0_32K                         1,262,276 (25 MB/s)    2,739,665 (11 MB/s)              1,477,389  117.04%   x 0.46 
 misc::easy1_1K                          39,959 (26 MB/s)       85,733 (12 MB/s)                    45,774  114.55%   x 0.47 
 misc::easy1_1MB                         40,379,174 (25 MB/s)   89,193,091 (11 MB/s)            48,813,917  120.89%   x 0.45 
 misc::easy1_32                          1,833 (28 MB/s)        3,131 (16 MB/s)                      1,298   70.81%   x 0.59 
 misc::easy1_32K                         1,262,166 (25 MB/s)    2,771,313 (11 MB/s)              1,509,147  119.57%   x 0.46 
 misc::hard_1K                           999,561 (1 MB/s)       2,649,272                        1,649,711  165.04%   x 0.38 
 misc::hard_1MB                          1,059,059,453          3,797,731,631                2,738,672,178  258.59%   x 0.28 
 misc::hard_32                           30,532 (1 MB/s)        106,727                             76,195  249.56%   x 0.29 
 misc::hard_32K                          34,627,995             118,202,589                     83,574,594  241.35%   x 0.29 
 misc::literal                           2,146 (23 MB/s)        5,257 (9 MB/s)                       3,111  144.97%   x 0.41 
 misc::long_needle1                      29,212,899 (3 MB/s)    26,957,831 (3 MB/s)             -2,255,068   -7.72%   x 1.08 
 misc::long_needle2                      29,231,653 (3 MB/s)    26,961,623 (3 MB/s)             -2,270,030   -7.77%   x 1.08 
 misc::match_class                       3,404 (23 MB/s)        9,461 (8 MB/s)                       6,057  177.94%   x 0.36 
 misc::match_class_in_range              3,399 (23 MB/s)        9,142 (8 MB/s)                       5,743  168.96%   x 0.37 
 misc::medium_1K                         41,221 (25 MB/s)       117,010 (8 MB/s)                    75,789  183.86%   x 0.35 
 misc::medium_1MB                        41,618,788 (25 MB/s)   118,524,120 (8 MB/s)            76,905,332  184.79%   x 0.35 
 misc::medium_32                         1,862 (32 MB/s)        4,056 (14 MB/s)                      2,194  117.83%   x 0.46 
 misc::medium_32K                        1,300,733 (25 MB/s)    3,719,397 (8 MB/s)               2,418,664  185.95%   x 0.35 
 misc::not_literal                       2,888 (17 MB/s)        5,695 (8 MB/s)                       2,807   97.20%   x 0.51 
 misc::one_pass_long_prefix              571 (45 MB/s)          496 (52 MB/s)                          -75  -13.13%   x 1.15 
 misc::one_pass_long_prefix_not          580 (44 MB/s)          504 (51 MB/s)                          -76  -13.10%   x 1.15 
 misc::one_pass_short                    1,733 (9 MB/s)         5,272 (3 MB/s)                       3,539  204.21%   x 0.33 
 misc::one_pass_short_not                1,717 (9 MB/s)         5,261 (3 MB/s)                       3,544  206.41%   x 0.33 
 misc::reallyhard2_1K                    996,324 (1 MB/s)       3,690,062                        2,693,738  270.37%   x 0.27 
 misc::reallyhard_1K                     1,012,203 (1 MB/s)     3,481,170                        2,468,967  243.92%   x 0.29 
 misc::reallyhard_1MB                    1,053,934,632          3,817,934,222                2,763,999,590  262.26%   x 0.28 
 misc::reallyhard_32                     30,234 (1 MB/s)        109,921                             79,687  263.57%   x 0.28 
 misc::reallyhard_32K                    34,378,406             119,029,510                     84,651,104  246.23%   x 0.29 
 misc::reverse_suffix_no_quadratic       331,368 (24 MB/s)      1,256,212 (6 MB/s)                 924,844  279.10%   x 0.26 
 regexdna::find_new_lines                307,181,237 (16 MB/s)  1,284,621,704 (3 MB/s)         977,440,467  318.20%   x 0.24 
 regexdna::subst1                        201,886,931 (25 MB/s)  527,021,759 (9 MB/s)           325,134,828  161.05%   x 0.38 
 regexdna::subst10                       207,618,870 (24 MB/s)  526,546,878 (9 MB/s)           318,928,008  153.61%   x 0.39 
 regexdna::subst11                       201,880,614 (25 MB/s)  526,708,991 (9 MB/s)           324,828,377  160.90%   x 0.38 
 regexdna::subst2                        201,861,384 (25 MB/s)  526,847,458 (9 MB/s)           324,986,074  160.99%   x 0.38 
 regexdna::subst3                        207,640,785 (24 MB/s)  526,948,528 (9 MB/s)           319,307,743  153.78%   x 0.39 
 regexdna::subst4                        201,919,815 (25 MB/s)  526,985,130 (9 MB/s)           325,065,315  160.99%   x 0.38 
 regexdna::subst5                        201,899,802 (25 MB/s)  527,437,908 (9 MB/s)           325,538,106  161.24%   x 0.38 
 regexdna::subst6                        201,878,177 (25 MB/s)  527,479,378 (9 MB/s)           325,601,201  161.29%   x 0.38 
 regexdna::subst7                        201,941,772 (25 MB/s)  527,953,799 (9 MB/s)           326,012,027  161.44%   x 0.38 
 regexdna::subst8                        201,896,316 (25 MB/s)  527,342,237 (9 MB/s)           325,445,921  161.19%   x 0.38 
 regexdna::subst9                        201,911,005 (25 MB/s)  527,438,904 (9 MB/s)           325,527,899  161.22%   x 0.38 
 regexdna::variant1                      336,160,741 (15 MB/s)  1,010,887,257 (5 MB/s)         674,726,516  200.72%   x 0.33 
 regexdna::variant2                      392,650,258 (12 MB/s)  1,089,425,668 (4 MB/s)         696,775,410  177.45%   x 0.36 
 regexdna::variant3                      351,431,623 (14 MB/s)  1,032,152,315 (4 MB/s)         680,720,692  193.70%   x 0.34 
 regexdna::variant4                      338,043,444 (15 MB/s)  1,010,674,047 (5 MB/s)         672,630,603  198.98%   x 0.33 
 regexdna::variant5                      334,627,689 (15 MB/s)  1,008,361,582 (5 MB/s)         673,733,893  201.34%   x 0.33 
 regexdna::variant6                      336,059,615 (15 MB/s)  1,008,898,749 (5 MB/s)         672,839,134  200.21%   x 0.33 
 regexdna::variant7                      338,298,685 (15 MB/s)  1,031,132,197 (4 MB/s)         692,833,512  204.80%   x 0.33 
 regexdna::variant8                      348,758,502 (14 MB/s)  1,030,161,360 (4 MB/s)         681,402,858  195.38%   x 0.34 
 regexdna::variant9                      401,088,309 (12 MB/s)  1,113,209,565 (4 MB/s)         712,121,256  177.55%   x 0.36 
 sherlock::before_after_holmes           103,667,977 (5 MB/s)   438,719,314 (1 MB/s)           335,051,337  323.20%   x 0.24 
 sherlock::before_holmes                 103,809,888 (5 MB/s)   435,017,143 (1 MB/s)           331,207,255  319.05%   x 0.24 
 sherlock::everything_greedy             30,140,710 (19 MB/s)   84,845,207 (7 MB/s)             54,704,497  181.50%   x 0.36 
 sherlock::holmes_cochar_watson          34,338,985 (17 MB/s)   152,597,042 (3 MB/s)           118,258,057  344.38%   x 0.23 
 sherlock::ing_suffix                    83,871,295 (7 MB/s)    363,493,715 (1 MB/s)           279,622,420  333.39%   x 0.23 
 sherlock::ing_suffix_limited_space      48,593,384 (12 MB/s)   189,511,962 (3 MB/s)           140,918,578  290.00%   x 0.26 
 sherlock::name_alt1                     33,965,251 (17 MB/s)   110,852,300 (5 MB/s)            76,887,049  226.37%   x 0.31 
 sherlock::name_alt2                     34,131,786 (17 MB/s)   110,546,990 (5 MB/s)            76,415,204  223.88%   x 0.31 
 sherlock::name_alt3                     74,160,916 (8 MB/s)    306,030,626 (1 MB/s)           231,869,710  312.66%   x 0.24 
 sherlock::name_alt4                     34,333,961 (17 MB/s)   150,583,425 (3 MB/s)           116,249,464  338.58%   x 0.23 
 sherlock::name_alt5                     41,481,282 (14 MB/s)   161,599,873 (3 MB/s)           120,118,591  289.57%   x 0.26 
 sherlock::name_holmes                   22,940,321 (25 MB/s)   61,346,516 (9 MB/s)             38,406,195  167.42%   x 0.37 
 sherlock::name_sherlock                 22,915,858 (25 MB/s)   61,440,605 (9 MB/s)             38,524,747  168.11%   x 0.37 
 sherlock::name_sherlock_holmes          22,899,246 (25 MB/s)   61,409,060 (9 MB/s)             38,509,814  168.17%   x 0.37 
 sherlock::name_whitespace               22,901,419 (25 MB/s)   81,503,927 (7 MB/s)             58,602,508  255.89%   x 0.28 
 sherlock::no_match_common               23,403,282 (25 MB/s)   61,847,966 (9 MB/s)             38,444,684  164.27%   x 0.38 
 sherlock::no_match_really_common        23,404,467 (25 MB/s)   61,909,203 (9 MB/s)             38,504,736  164.52%   x 0.38 
 sherlock::no_match_uncommon             22,917,887 (25 MB/s)   61,401,813 (9 MB/s)             38,483,926  167.92%   x 0.37 
 sherlock::quotes                        29,375,307 (20 MB/s)   104,884,795 (5 MB/s)            75,509,488  257.05%   x 0.28 
 sherlock::repeated_class_negation       53,412,556 (11 MB/s)   242,837,125 (2 MB/s)           189,424,569  354.64%   x 0.22 
 sherlock::the_lower                     26,024,165 (22 MB/s)   61,100,595 (9 MB/s)             35,076,430  134.78%   x 0.43 
 sherlock::the_upper                     23,689,507 (25 MB/s)   61,979,148 (9 MB/s)             38,289,641  161.63%   x 0.38 
 sherlock::the_whitespace                24,354,227 (24 MB/s)   82,346,850 (7 MB/s)             57,992,623  238.12%   x 0.30 
 sherlock::word_ending_n                 163,437,469 (3 MB/s)   169,223,443 (3 MB/s)             5,785,974    3.54%   x 0.97 

[1] https://libcxx.llvm.org/docs/UsingLibcxx.html

@mkrupcale
Copy link
Contributor Author

I've added support for benchmarking against Boost.Regex. The benchmark implementation reuses the Rust and C/C++ FFIs from stdcpp by just making some small changes based on the compiler preprocessor directives because the Boost.Regex API is so similar to the std::regex API. In several tests, Boost.Regex is on the order of 10 times faster than libstdc++, although it is still usually slower than RE2. Here are some numbers on my machine for Boost.Regex (Boost version 1.64.0):

running 81 tests
test misc::anchored_literal_long_match      ... bench:         265 ns/iter (+/- 5) = 1471 MB/s
test misc::anchored_literal_long_non_match  ... bench:         620 ns/iter (+/- 14) = 629 MB/s
test misc::anchored_literal_short_match     ... bench:         271 ns/iter (+/- 6) = 95 MB/s
test misc::anchored_literal_short_non_match ... bench:         228 ns/iter (+/- 13) = 114 MB/s
test misc::easy0_1K                         ... bench:       1,167 ns/iter (+/- 712) = 900 MB/s
test misc::easy0_1MB                        ... bench:     973,502 ns/iter (+/- 250,311) = 1077 MB/s
test misc::easy0_32                         ... bench:         279 ns/iter (+/- 34) = 211 MB/s
test misc::easy0_32K                        ... bench:      29,364 ns/iter (+/- 15,763) = 1116 MB/s
test misc::easy1_1K                         ... bench:       1,284 ns/iter (+/- 758) = 813 MB/s
test misc::easy1_1MB                        ... bench:     955,152 ns/iter (+/- 6,126) = 1097 MB/s
test misc::easy1_32                         ... bench:         458 ns/iter (+/- 2) = 113 MB/s
test misc::easy1_32K                        ... bench:      29,501 ns/iter (+/- 148) = 1111 MB/s
test misc::hard_1K                          ... bench:     120,775 ns/iter (+/- 382) = 8 MB/s
test misc::hard_1MB                         ... bench: 126,685,367 ns/iter (+/- 391,406) = 8 MB/s
test misc::hard_32                          ... bench:       4,021 ns/iter (+/- 6) = 14 MB/s
test misc::hard_32K                         ... bench:   3,946,673 ns/iter (+/- 14,141) = 8 MB/s
test misc::literal                          ... bench:         255 ns/iter (+/- 2) = 200 MB/s
test misc::long_needle1                     ... bench:   9,356,835 ns/iter (+/- 19,988) = 10 MB/s
test misc::long_needle2                     ... bench:   9,355,766 ns/iter (+/- 9,808) = 10 MB/s
test misc::match_class                      ... bench:         278 ns/iter (+/- 1) = 291 MB/s
test misc::match_class_in_range             ... bench:         280 ns/iter (+/- 3) = 289 MB/s
test misc::medium_1K                        ... bench:       1,190 ns/iter (+/- 3) = 884 MB/s
test misc::medium_1MB                       ... bench:     950,317 ns/iter (+/- 1,508) = 1103 MB/s
test misc::medium_32                        ... bench:         307 ns/iter (+/- 0) = 195 MB/s
test misc::medium_32K                       ... bench:      29,191 ns/iter (+/- 60) = 1123 MB/s
test misc::no_exponential                   ... bench:       2,400 ns/iter (+/- 18) = 41 MB/s
test misc::not_literal                      ... bench:       2,480 ns/iter (+/- 16) = 20 MB/s
test misc::one_pass_long_prefix             ... bench:         314 ns/iter (+/- 1) = 82 MB/s
test misc::one_pass_long_prefix_not         ... bench:         318 ns/iter (+/- 6) = 81 MB/s
test misc::one_pass_short                   ... bench:       1,860 ns/iter (+/- 10) = 9 MB/s
test misc::one_pass_short_not               ... bench:       1,835 ns/iter (+/- 3) = 9 MB/s
test misc::reallyhard2_1K                   ... bench:       8,731 ns/iter (+/- 24) = 119 MB/s
test misc::reallyhard_1K                    ... bench:     123,212 ns/iter (+/- 257) = 8 MB/s
test misc::reallyhard_1MB                   ... bench: 126,461,155 ns/iter (+/- 201,007) = 8 MB/s
test misc::reallyhard_32                    ... bench:       4,052 ns/iter (+/- 15) = 14 MB/s
test misc::reallyhard_32K                   ... bench:   3,951,448 ns/iter (+/- 15,950) = 8 MB/s
test misc::reverse_suffix_no_quadratic      ... bench:       7,238 ns/iter (+/- 37) = 1105 MB/s
test regexdna::find_new_lines               ... bench:  22,191,268 ns/iter (+/- 180,759) = 229 MB/s
test regexdna::subst1                       ... bench:  11,328,494 ns/iter (+/- 429,399) = 448 MB/s
test regexdna::subst10                      ... bench:  11,130,192 ns/iter (+/- 185,463) = 456 MB/s
test regexdna::subst11                      ... bench:  11,150,335 ns/iter (+/- 296,241) = 455 MB/s
test regexdna::subst2                       ... bench:  11,080,094 ns/iter (+/- 190,980) = 458 MB/s
test regexdna::subst3                       ... bench:  11,214,685 ns/iter (+/- 224,049) = 453 MB/s
test regexdna::subst4                       ... bench:  11,176,540 ns/iter (+/- 242,372) = 454 MB/s
test regexdna::subst5                       ... bench:  11,176,037 ns/iter (+/- 235,311) = 454 MB/s
test regexdna::subst6                       ... bench:  11,118,229 ns/iter (+/- 247,708) = 457 MB/s
test regexdna::subst7                       ... bench:  11,122,259 ns/iter (+/- 197,509) = 457 MB/s
test regexdna::subst8                       ... bench:  11,146,950 ns/iter (+/- 232,173) = 456 MB/s
test regexdna::subst9                       ... bench:  11,203,006 ns/iter (+/- 211,097) = 453 MB/s
test regexdna::variant1                     ... bench: 119,023,604 ns/iter (+/- 121,832) = 42 MB/s
test regexdna::variant2                     ... bench: 196,640,467 ns/iter (+/- 2,171,890) = 25 MB/s
test regexdna::variant3                     ... bench: 140,370,307 ns/iter (+/- 120,910) = 36 MB/s
test regexdna::variant4                     ... bench: 122,655,848 ns/iter (+/- 170,311) = 41 MB/s
test regexdna::variant5                     ... bench: 120,366,844 ns/iter (+/- 338,744) = 42 MB/s
test regexdna::variant6                     ... bench: 120,683,844 ns/iter (+/- 111,003) = 42 MB/s
test regexdna::variant7                     ... bench: 125,327,969 ns/iter (+/- 118,787) = 40 MB/s
test regexdna::variant8                     ... bench: 139,814,719 ns/iter (+/- 122,010) = 36 MB/s
test regexdna::variant9                     ... bench: 185,594,354 ns/iter (+/- 780,519) = 27 MB/s
test sherlock::before_after_holmes          ... bench:  12,461,426 ns/iter (+/- 25,738) = 47 MB/s
test sherlock::before_holmes                ... bench:  12,464,665 ns/iter (+/- 100,160) = 47 MB/s
test sherlock::holmes_cochar_watson         ... bench:     691,879 ns/iter (+/- 2,046) = 859 MB/s
test sherlock::ing_suffix                   ... bench:  10,735,512 ns/iter (+/- 11,757) = 55 MB/s
test sherlock::ing_suffix_limited_space     ... bench:  13,895,222 ns/iter (+/- 114,016) = 42 MB/s
test sherlock::name_alt1                    ... bench:     636,387 ns/iter (+/- 951) = 934 MB/s
test sherlock::name_alt2                    ... bench:     742,319 ns/iter (+/- 1,710) = 801 MB/s
test sherlock::name_alt3                    ... bench:   1,218,571 ns/iter (+/- 2,443) = 488 MB/s
test sherlock::name_alt4                    ... bench:     763,738 ns/iter (+/- 2,207) = 778 MB/s
test sherlock::name_alt5                    ... bench:     816,228 ns/iter (+/- 3,797) = 728 MB/s
test sherlock::name_holmes                  ... bench:     679,777 ns/iter (+/- 1,042) = 875 MB/s
test sherlock::name_sherlock                ... bench:     593,721 ns/iter (+/- 674) = 1002 MB/s
test sherlock::name_sherlock_holmes         ... bench:     590,540 ns/iter (+/- 2,641) = 1007 MB/s
test sherlock::name_whitespace              ... bench:     597,332 ns/iter (+/- 2,186) = 995 MB/s
test sherlock::no_match_common              ... bench:   2,032,167 ns/iter (+/- 4,947) = 292 MB/s
test sherlock::no_match_really_common       ... bench:   2,031,975 ns/iter (+/- 1,816) = 292 MB/s
test sherlock::no_match_uncommon            ... bench:     543,526 ns/iter (+/- 1,894) = 1094 MB/s
test sherlock::quotes                       ... bench:   1,504,299 ns/iter (+/- 2,143) = 395 MB/s
test sherlock::repeated_class_negation      ... bench:  22,540,328 ns/iter (+/- 17,719) = 26 MB/s
test sherlock::the_lower                    ... bench:   3,551,085 ns/iter (+/- 9,694) = 167 MB/s
test sherlock::the_upper                    ... bench:     720,753 ns/iter (+/- 2,948) = 825 MB/s
test sherlock::the_whitespace               ... bench:   3,429,084 ns/iter (+/- 10,561) = 173 MB/s
test sherlock::word_ending_n                ... bench:  13,706,182 ns/iter (+/- 15,718) = 43 MB/s

test result: ok. 0 passed; 0 failed; 0 ignored; 81 measured; 0 filtered out

@mkrupcale
Copy link
Contributor Author

Small update: I've enabled some additional tests for re-boost since Boost.Regex grammar does appear to support the inline modifier syntax. Here are updated numbers (again Boost 1.64.0):

running 90 tests
test misc::anchored_literal_long_match       ... bench:         256 ns/iter (+/- 7) = 1523 MB/s
test misc::anchored_literal_long_non_match   ... bench:         608 ns/iter (+/- 3) = 641 MB/s
test misc::anchored_literal_short_match      ... bench:         266 ns/iter (+/- 10) = 97 MB/s
test misc::anchored_literal_short_non_match  ... bench:         224 ns/iter (+/- 2) = 116 MB/s
test misc::easy0_1K                          ... bench:       1,155 ns/iter (+/- 10) = 909 MB/s
test misc::easy0_1MB                         ... bench:     954,005 ns/iter (+/- 8,532) = 1099 MB/s
test misc::easy0_32                          ... bench:         279 ns/iter (+/- 4) = 211 MB/s
test misc::easy0_32K                         ... bench:      29,443 ns/iter (+/- 379) = 1113 MB/s
test misc::easy1_1K                          ... bench:       1,277 ns/iter (+/- 21) = 817 MB/s
test misc::easy1_1MB                         ... bench:     953,971 ns/iter (+/- 4,203) = 1099 MB/s
test misc::easy1_32                          ... bench:         381 ns/iter (+/- 5) = 136 MB/s
test misc::easy1_32K                         ... bench:      29,469 ns/iter (+/- 262) = 1112 MB/s
test misc::hard_1K                           ... bench:     102,045 ns/iter (+/- 634) = 10 MB/s
test misc::hard_1MB                          ... bench: 126,568,720 ns/iter (+/- 18,762,247) = 8 MB/s
test misc::hard_32                           ... bench:       4,029 ns/iter (+/- 9) = 14 MB/s
test misc::hard_32K                          ... bench:   3,956,061 ns/iter (+/- 12,118) = 8 MB/s
test misc::literal                           ... bench:         256 ns/iter (+/- 2) = 199 MB/s
test misc::long_needle1                      ... bench:   9,438,214 ns/iter (+/- 40,681) = 10 MB/s
test misc::long_needle2                      ... bench:   9,439,532 ns/iter (+/- 39,863) = 10 MB/s
test misc::match_class                       ... bench:         277 ns/iter (+/- 1) = 292 MB/s
test misc::match_class_in_range              ... bench:         279 ns/iter (+/- 1) = 290 MB/s
test misc::medium_1K                         ... bench:       1,184 ns/iter (+/- 3) = 888 MB/s
test misc::medium_1MB                        ... bench:     954,113 ns/iter (+/- 3,768) = 1099 MB/s
test misc::medium_32                         ... bench:         303 ns/iter (+/- 0) = 198 MB/s
test misc::medium_32K                        ... bench:      29,376 ns/iter (+/- 79) = 1116 MB/s
test misc::no_exponential                    ... bench:       2,379 ns/iter (+/- 8) = 42 MB/s
test misc::not_literal                       ... bench:       2,514 ns/iter (+/- 19) = 20 MB/s
test misc::one_pass_long_prefix              ... bench:         299 ns/iter (+/- 0) = 86 MB/s
test misc::one_pass_long_prefix_not          ... bench:         318 ns/iter (+/- 1) = 81 MB/s
test misc::one_pass_short                    ... bench:       1,844 ns/iter (+/- 8) = 9 MB/s
test misc::one_pass_short_not                ... bench:       1,837 ns/iter (+/- 7) = 9 MB/s
test misc::reallyhard2_1K                    ... bench:       8,838 ns/iter (+/- 48) = 117 MB/s
test misc::reallyhard_1K                     ... bench:     123,391 ns/iter (+/- 752) = 8 MB/s
test misc::reallyhard_1MB                    ... bench: 126,781,102 ns/iter (+/- 592,971) = 8 MB/s
test misc::reallyhard_32                     ... bench:       4,092 ns/iter (+/- 10) = 14 MB/s
test misc::reallyhard_32K                    ... bench:   3,958,936 ns/iter (+/- 21,134) = 8 MB/s
test misc::reverse_suffix_no_quadratic       ... bench:       7,260 ns/iter (+/- 32) = 1101 MB/s
test regexdna::find_new_lines                ... bench:  22,388,250 ns/iter (+/- 770,485) = 227 MB/s
test regexdna::subst1                        ... bench:  11,240,386 ns/iter (+/- 584,418) = 452 MB/s
test regexdna::subst10                       ... bench:  11,081,007 ns/iter (+/- 577,399) = 458 MB/s
test regexdna::subst11                       ... bench:  11,247,837 ns/iter (+/- 549,076) = 451 MB/s
test regexdna::subst2                        ... bench:  11,172,853 ns/iter (+/- 293,845) = 454 MB/s
test regexdna::subst3                        ... bench:  11,163,271 ns/iter (+/- 1,900,364) = 455 MB/s
test regexdna::subst4                        ... bench:  11,073,543 ns/iter (+/- 501,978) = 459 MB/s
test regexdna::subst5                        ... bench:  11,096,057 ns/iter (+/- 248,372) = 458 MB/s
test regexdna::subst6                        ... bench:  11,225,641 ns/iter (+/- 681,976) = 452 MB/s
test regexdna::subst7                        ... bench:  11,254,748 ns/iter (+/- 558,395) = 451 MB/s
test regexdna::subst8                        ... bench:  11,195,961 ns/iter (+/- 490,545) = 454 MB/s
test regexdna::subst9                        ... bench:  11,057,015 ns/iter (+/- 157,962) = 459 MB/s
test regexdna::variant1                      ... bench: 120,691,009 ns/iter (+/- 453,706) = 42 MB/s
test regexdna::variant2                      ... bench: 198,285,397 ns/iter (+/- 1,037,404) = 25 MB/s
test regexdna::variant3                      ... bench: 142,091,900 ns/iter (+/- 902,040) = 35 MB/s
test regexdna::variant4                      ... bench: 123,788,411 ns/iter (+/- 250,544) = 41 MB/s
test regexdna::variant5                      ... bench: 121,812,008 ns/iter (+/- 119,700) = 41 MB/s
test regexdna::variant6                      ... bench: 121,962,094 ns/iter (+/- 402,350) = 41 MB/s
test regexdna::variant7                      ... bench: 125,797,875 ns/iter (+/- 354,136) = 40 MB/s
test regexdna::variant8                      ... bench: 141,723,961 ns/iter (+/- 321,211) = 35 MB/s
test regexdna::variant9                      ... bench: 186,977,633 ns/iter (+/- 985,315) = 27 MB/s
test sherlock::before_after_holmes           ... bench:  12,756,829 ns/iter (+/- 86,882) = 46 MB/s
test sherlock::before_holmes                 ... bench:  12,716,889 ns/iter (+/- 115,382) = 46 MB/s
test sherlock::everything_greedy_nl          ... bench:         450 ns/iter (+/- 1) = 1322073 MB/s
test sherlock::holmes_cochar_watson          ... bench:     698,251 ns/iter (+/- 3,479) = 852 MB/s
test sherlock::ing_suffix                    ... bench:  10,822,209 ns/iter (+/- 62,155) = 54 MB/s
test sherlock::ing_suffix_limited_space      ... bench:  14,174,655 ns/iter (+/- 79,673) = 41 MB/s
test sherlock::line_boundary_sherlock_holmes ... bench:     636,773 ns/iter (+/- 4,107) = 934 MB/s
test sherlock::name_alt1                     ... bench:     634,460 ns/iter (+/- 4,490) = 937 MB/s
test sherlock::name_alt2                     ... bench:     754,125 ns/iter (+/- 2,947) = 788 MB/s
test sherlock::name_alt3                     ... bench:   1,203,445 ns/iter (+/- 4,817) = 494 MB/s
test sherlock::name_alt3_nocase              ... bench:  15,939,335 ns/iter (+/- 110,027) = 37 MB/s
test sherlock::name_alt4                     ... bench:     764,239 ns/iter (+/- 1,552) = 778 MB/s
test sherlock::name_alt4_nocase              ... bench:   6,080,371 ns/iter (+/- 47,978) = 97 MB/s
test sherlock::name_alt5                     ... bench:     819,112 ns/iter (+/- 1,614) = 726 MB/s
test sherlock::name_alt5_nocase              ... bench:   7,392,905 ns/iter (+/- 13,981) = 80 MB/s
test sherlock::name_holmes                   ... bench:     676,172 ns/iter (+/- 1,259) = 879 MB/s
test sherlock::name_holmes_nocase            ... bench:   3,477,820 ns/iter (+/- 23,984) = 171 MB/s
test sherlock::name_sherlock                 ... bench:     592,899 ns/iter (+/- 4,787) = 1003 MB/s
test sherlock::name_sherlock_holmes          ... bench:     595,950 ns/iter (+/- 5,200) = 998 MB/s
test sherlock::name_sherlock_holmes_nocase   ... bench:   3,272,100 ns/iter (+/- 6,853) = 181 MB/s
test sherlock::name_sherlock_nocase          ... bench:   3,257,587 ns/iter (+/- 2,985) = 182 MB/s
test sherlock::name_whitespace               ... bench:     596,336 ns/iter (+/- 1,699) = 997 MB/s
test sherlock::no_match_common               ... bench:   2,037,471 ns/iter (+/- 3,229) = 291 MB/s
test sherlock::no_match_really_common        ... bench:   2,035,410 ns/iter (+/- 3,126) = 292 MB/s
test sherlock::no_match_uncommon             ... bench:     547,831 ns/iter (+/- 4,946) = 1085 MB/s
test sherlock::quotes                        ... bench:   1,538,964 ns/iter (+/- 5,257) = 386 MB/s
test sherlock::repeated_class_negation       ... bench:  23,493,585 ns/iter (+/- 28,717) = 25 MB/s
test sherlock::the_lower                     ... bench:   3,546,763 ns/iter (+/- 19,650) = 167 MB/s
test sherlock::the_nocase                    ... bench:   5,920,620 ns/iter (+/- 26,590) = 100 MB/s
test sherlock::the_upper                     ... bench:     720,192 ns/iter (+/- 4,933) = 826 MB/s
test sherlock::the_whitespace                ... bench:   3,483,809 ns/iter (+/- 11,171) = 170 MB/s
test sherlock::word_ending_n                 ... bench:  13,801,591 ns/iter (+/- 52,403) = 43 MB/s

test result: ok. 0 passed; 0 failed; 0 ignored; 90 measured; 0 filtered out

This is very similar to the `std::regex` benchmark implementation since Boost.Regex and `std::regex` have very similar APIs and regex grammar support. As such, it uses the `stdcpp` Rust and C FFIs to reduce code duplication.

 * bench/Cargo.toml: add `re-boost` feature
 * bench/build.rs: add `cboost` library to bench build. This uses a compiler preprocessor definition to indicate whether or not to use Boost when compiling the `stdcpp` FFI.
 * bench/compile: add `re-boost` feature to bench compile script
 * bench/run: add `re-boost` feature to bench run script
 * bench/src/bench.rs: use `ffi::stdcpp::Regex`, define its `text!` macro, and `Text` type for feature `re-boost`
 * bench/src/ffi/mod.rs: declare `stdcpp` module for `re-boost` feature
 * bench/src/ffi/stdcpp.cpp: implement C API using C++ `boost::regex`. The Boost.Regex API is very similar to the `std::regex` API and therefore only uses a different namespace.
 * bench/src/main.rs: add boost to bench main
 * bench/src/misc.rs:
    - do not run `match_class_unicode` benchmark for `re-boost` feature because `boost::regex` ECMAScript grammar does not support unicode character classes
 * bench/src/sherlock.rs:
    - do not run `letters`, `letters_upper`, and `letters_lower` benchmarks for `re-boost` feature because `boost::regex` ECMAScript grammar does not support unicode character classes
    - use a different regex for `everything_greedy` benchmark because `boost::regex` '.' does not match '\r'
    - `words` benchmark for `boost::regex` matches RE2 test result, so use that test for `re-boost` feature as well. Also fixes conditional compilation issue for `re-stdcpp`.
    - do not run `holmes_coword_watson` benchmark for `re-boost` feature because Boost.Regex implementation currently seems to have exponential behavior here
@mkrupcale
Copy link
Contributor Author

Fixed some conditional compilation issues which were not enabling some tests as I had thought. On a side note, I do not particularly like the syntax for conditional compilation in Rust. It is not obvious how it works when compared to C/C++ preprocessor directives. In any case, I have some comparisons (82 tests) between std::regex and Boost.Regex here:

 name                                    stdcpp.bench ns/iter    boost.bench ns/iter    diff ns/iter   diff %   speedup 
 misc::anchored_literal_long_match       326 (1196 MB/s)         254 (1535 MB/s)                 -72  -22.09%    x 1.28 
 misc::anchored_literal_long_non_match   14,961 (26 MB/s)        610 (639 MB/s)              -14,351  -95.92%   x 24.53 
 misc::anchored_literal_short_match      324 (80 MB/s)           265 (98 MB/s)                   -59  -18.21%    x 1.22 
 misc::anchored_literal_short_non_match  1,188 (21 MB/s)         224 (116 MB/s)                 -964  -81.14%    x 5.30 
 misc::easy0_1K                          40,259 (26 MB/s)        1,154 (910 MB/s)            -39,105  -97.13%   x 34.89 
 misc::easy0_1MB                         27,620,524 (37 MB/s)    965,616 (1085 MB/s)     -26,654,908  -96.50%   x 28.60 
 misc::easy0_32                          1,333 (44 MB/s)         274 (215 MB/s)               -1,059  -79.44%    x 4.86 
 misc::easy0_32K                         860,515 (38 MB/s)       29,218 (1122 MB/s)         -831,297  -96.60%   x 29.45 
 misc::easy1_1K                          27,266 (38 MB/s)        1,262 (827 MB/s)            -26,004  -95.37%   x 21.61 
 misc::easy1_1MB                         27,570,037 (38 MB/s)    954,587 (1098 MB/s)     -26,615,450  -96.54%   x 28.88 
 misc::easy1_32                          1,290 (40 MB/s)         382 (136 MB/s)                 -908  -70.39%    x 3.38 
 misc::easy1_32K                         859,847 (38 MB/s)       29,367 (1116 MB/s)         -830,480  -96.58%   x 29.28 
 misc::hard_1K                           691,984 (1 MB/s)        101,793 (10 MB/s)          -590,191  -85.29%    x 6.80 
 misc::hard_1MB                          752,023,938 (1 MB/s)    107,743,602 (9 MB/s)   -644,280,336  -85.67%    x 6.98 
 misc::hard_32                           29,569 (1 MB/s)         3,382 (17 MB/s)             -26,187  -88.56%    x 8.74 
 misc::hard_32K                          32,655,030 (1 MB/s)     3,344,428 (9 MB/s)      -29,310,602  -89.76%    x 9.76 
 misc::literal                           2,158 (23 MB/s)         242 (210 MB/s)               -1,916  -88.79%    x 8.92 
 misc::long_needle1                      29,331,421 (3 MB/s)     8,699,576 (11 MB/s)     -20,631,845  -70.34%    x 3.37 
 misc::long_needle2                      29,253,783 (3 MB/s)     8,700,623 (11 MB/s)     -20,553,160  -70.26%    x 3.36 
 misc::match_class                       3,377 (23 MB/s)         263 (307 MB/s)               -3,114  -92.21%   x 12.84 
 misc::match_class_in_range              3,369 (24 MB/s)         267 (303 MB/s)               -3,102  -92.07%   x 12.62 
 misc::medium_1K                         40,886 (25 MB/s)        1,188 (885 MB/s)            -39,698  -97.09%   x 34.42 
 misc::medium_1MB                        41,303,418 (25 MB/s)    968,985 (1082 MB/s)     -40,334,433  -97.65%   x 42.63 
 misc::medium_32                         1,824 (32 MB/s)         284 (211 MB/s)               -1,540  -84.43%    x 6.42 
 misc::medium_32K                        1,290,806 (25 MB/s)     29,442 (1113 MB/s)       -1,261,364  -97.72%   x 43.84 
 misc::not_literal                       2,909 (17 MB/s)         1,918 (26 MB/s)                -991  -34.07%    x 1.52 
 misc::one_pass_long_prefix              551 (47 MB/s)           265 (98 MB/s)                  -286  -51.91%    x 2.08 
 misc::one_pass_long_prefix_not          559 (46 MB/s)           275 (94 MB/s)                  -284  -50.81%    x 2.03 
 misc::one_pass_short                    1,675 (10 MB/s)         1,454 (11 MB/s)                -221  -13.19%    x 1.15 
 misc::one_pass_short_not                1,659 (10 MB/s)         1,448 (11 MB/s)                -211  -12.72%    x 1.15 
 misc::reallyhard2_1K                    1,029,782 (1 MB/s)      8,077 (128 MB/s)         -1,021,705  -99.22%  x 127.50 
 misc::reallyhard_1K                     977,281 (1 MB/s)        104,789 (10 MB/s)          -872,492  -89.28%    x 9.33 
 misc::reallyhard_1MB                    1,047,257,825 (1 MB/s)  107,224,799 (9 MB/s)   -940,033,026  -89.76%    x 9.77 
 misc::reallyhard_32                     29,663 (1 MB/s)         3,478 (16 MB/s)             -26,185  -88.27%    x 8.53 
 misc::reallyhard_32K                    32,656,288 (1 MB/s)     3,346,344 (9 MB/s)      -29,309,944  -89.75%    x 9.76 
 misc::reverse_suffix_no_quadratic       315,197 (25 MB/s)       7,254 (1102 MB/s)          -307,943  -97.70%   x 43.45 
 regexdna::find_new_lines                311,309,205 (16 MB/s)   21,292,931 (238 MB/s)  -290,016,274  -93.16%   x 14.62 
 regexdna::subst1                        203,506,467 (24 MB/s)   10,830,584 (469 MB/s)  -192,675,883  -94.68%   x 18.79 
 regexdna::subst10                       209,155,911 (24 MB/s)   11,013,409 (461 MB/s)  -198,142,502  -94.73%   x 18.99 
 regexdna::subst11                       203,304,330 (25 MB/s)   11,053,391 (459 MB/s)  -192,250,939  -94.56%   x 18.39 
 regexdna::subst2                        203,277,533 (25 MB/s)   11,130,110 (456 MB/s)  -192,147,423  -94.52%   x 18.26 
 regexdna::subst3                        203,369,831 (24 MB/s)   11,043,757 (460 MB/s)  -192,326,074  -94.57%   x 18.41 
 regexdna::subst4                        203,368,865 (24 MB/s)   10,987,304 (462 MB/s)  -192,381,561  -94.60%   x 18.51 
 regexdna::subst5                        203,529,515 (24 MB/s)   11,049,797 (460 MB/s)  -192,479,718  -94.57%   x 18.42 
 regexdna::subst6                        209,044,590 (24 MB/s)   10,995,047 (462 MB/s)  -198,049,543  -94.74%   x 19.01 
 regexdna::subst7                        203,468,880 (24 MB/s)   11,104,208 (457 MB/s)  -192,364,672  -94.54%   x 18.32 
 regexdna::subst8                        203,738,499 (24 MB/s)   11,016,615 (461 MB/s)  -192,721,884  -94.59%   x 18.49 
 regexdna::subst9                        203,626,289 (24 MB/s)   10,988,204 (462 MB/s)  -192,638,085  -94.60%   x 18.53 
 regexdna::variant1                      338,715,730 (15 MB/s)   118,627,986 (42 MB/s)  -220,087,744  -64.98%    x 2.86 
 regexdna::variant2                      403,485,774 (12 MB/s)   197,686,107 (25 MB/s)  -205,799,667  -51.01%    x 2.04 
 regexdna::variant3                      355,411,348 (14 MB/s)   141,013,037 (36 MB/s)  -214,398,311  -60.32%    x 2.52 
 regexdna::variant4                      340,240,582 (14 MB/s)   122,894,026 (41 MB/s)  -217,346,556  -63.88%    x 2.77 
 regexdna::variant5                      338,232,462 (15 MB/s)   120,081,690 (42 MB/s)  -218,150,772  -64.50%    x 2.82 
 regexdna::variant6                      338,863,229 (15 MB/s)   120,722,962 (42 MB/s)  -218,140,267  -64.37%    x 2.81 
 regexdna::variant7                      341,595,898 (14 MB/s)   125,160,905 (40 MB/s)  -216,434,993  -63.36%    x 2.73 
 regexdna::variant8                      352,487,285 (14 MB/s)   140,049,754 (36 MB/s)  -212,437,531  -60.27%    x 2.52 
 regexdna::variant9                      398,208,695 (12 MB/s)   186,701,676 (27 MB/s)  -211,507,019  -53.11%    x 2.13 
 sherlock::before_after_holmes           102,739,132 (5 MB/s)    12,501,058 (47 MB/s)    -90,238,074  -87.83%    x 8.22 
 sherlock::before_holmes                 102,767,992 (5 MB/s)    12,466,214 (47 MB/s)    -90,301,778  -87.87%    x 8.24 
 sherlock::everything_greedy             29,766,804 (19 MB/s)    6,488,811 (91 MB/s)     -23,277,993  -78.20%    x 4.59 
 sherlock::holmes_cochar_watson          35,020,759 (16 MB/s)    696,705 (853 MB/s)      -34,324,054  -98.01%   x 50.27 
 sherlock::ing_suffix                    83,304,107 (7 MB/s)     10,658,817 (55 MB/s)    -72,645,290  -87.20%    x 7.82 
 sherlock::ing_suffix_limited_space      49,350,976 (12 MB/s)    13,879,060 (42 MB/s)    -35,471,916  -71.88%    x 3.56 
 sherlock::name_alt1                     34,687,221 (17 MB/s)    637,820 (932 MB/s)      -34,049,401  -98.16%   x 54.38 
 sherlock::name_alt2                     34,864,055 (17 MB/s)    753,174 (789 MB/s)      -34,110,881  -97.84%   x 46.29 
 sherlock::name_alt3                     74,910,349 (7 MB/s)     1,208,281 (492 MB/s)    -73,702,068  -98.39%   x 62.00 
 sherlock::name_alt4                     34,578,655 (17 MB/s)    775,694 (766 MB/s)      -33,802,961  -97.76%   x 44.58 
 sherlock::name_alt5                     41,920,538 (14 MB/s)    829,909 (716 MB/s)      -41,090,629  -98.02%   x 50.51 
 sherlock::name_holmes                   23,162,259 (25 MB/s)    683,498 (870 MB/s)      -22,478,761  -97.05%   x 33.89 
 sherlock::name_sherlock                 23,133,786 (25 MB/s)    600,665 (990 MB/s)      -22,533,121  -97.40%   x 38.51 
 sherlock::name_sherlock_holmes          23,119,542 (25 MB/s)    596,294 (997 MB/s)      -22,523,248  -97.42%   x 38.77 
 sherlock::name_whitespace               23,121,151 (25 MB/s)    602,763 (987 MB/s)      -22,518,388  -97.39%   x 38.36 
 sherlock::no_match_common               23,600,506 (25 MB/s)    2,035,705 (292 MB/s)    -21,564,801  -91.37%   x 11.59 
 sherlock::no_match_really_common        23,601,146 (25 MB/s)    2,038,257 (291 MB/s)    -21,562,889  -91.36%   x 11.58 
 sherlock::no_match_uncommon             23,115,269 (25 MB/s)    545,924 (1089 MB/s)     -22,569,345  -97.64%   x 42.34 
 sherlock::quotes                        29,246,474 (20 MB/s)    1,504,658 (395 MB/s)    -27,741,816  -94.86%   x 19.44 
 sherlock::repeated_class_negation       53,399,045 (11 MB/s)    22,613,713 (26 MB/s)    -30,785,332  -57.65%    x 2.36 
 sherlock::the_lower                     24,700,649 (24 MB/s)    3,557,671 (167 MB/s)    -21,142,978  -85.60%    x 6.94 
 sherlock::the_upper                     23,231,354 (25 MB/s)    727,381 (817 MB/s)      -22,503,973  -96.87%   x 31.94 
 sherlock::the_whitespace                25,990,309 (22 MB/s)    3,428,141 (173 MB/s)    -22,562,168  -86.81%    x 7.58 
 sherlock::word_ending_n                 165,503,982 (3 MB/s)    13,993,274 (42 MB/s)   -151,510,708  -91.55%   x 11.83 
 sherlock::words                         46,421,873 (12 MB/s)    31,713,795 (18 MB/s)    -14,708,078  -31.68%    x 1.46 
WARNING: benchmarks in new but not in old: misc::no_exponential, sherlock::everything_greedy_nl, sherlock::line_boundary_sherlock_holmes, sherlock::name_alt3_nocase, sherlock::name_alt4_nocase, sherlock::name_alt5_nocase, sherlock::name_holmes_nocase, sherlock::name_sherlock_holmes_nocase, sherlock::name_sherlock_nocase, sherlock::the_nocase

@bstaletic
Copy link

A comment about libstdc++ (and libc++) regex library speed. It has nothing to do with bindings, it's just terribly slow. I have made some benchmarks that compare re2, boost::regex and std::regex a while ago. Boost was marginally, or should I say negligibly faster than re2, but both were between 2 and 2.5 times faster than std::regex. On top of that, before version GCC 5.0 came out, the libstdc++ implementation also wasn't tail recursive, so one of ycmd users managed to blow the stack (or at least the debugging seemed to point in that direction).

@BurntSushi
Copy link
Member

@mkrupcale I finally had a chance to test this out and it all works! Thanks so much for doing this. :-)

@mkrupcale
Copy link
Contributor Author

@BurntSushi no problem. Is there a reason why this pull request was closed, however? Seeing as there are benchmarks against other C and C++ regex implementations in this codebase, I'm not sure what the problem is with merging this additional set of C++ regex benchmarks. While I was doing this for my own interests, I don't see why it couldn't be useful to others and for future comparisons.

@BurntSushi
Copy link
Member

@mkrupcale Oh! This was merged in 4e3a107, which should be linked to this PR. I did the merge manually in order to clean up the commit messages. Sadly, the Github UI doesn't really distinguish between "manually merged PR" and "closed PR without merging."

@mkrupcale
Copy link
Contributor Author

Ah, that's my mistake. I didn't realize that was a reference to the merge commit. Apologies.

@BurntSushi
Copy link
Member

Yeah, lately I've been trying to keep a cleaner history for all of my projects by doing the following:

  • Banishing merge commits.
  • Making commit messages follow a certain format for consistency.
  • Most PRs get squashed down into a single commit. I can do this in the Github UI and even touch-up the commit message.

Your PR however was lovingly split into 3 sensible commits. So the only way to merge that while also touching up the messages is manually.

It's not clear if I will give up on this task yet or not, but so far it has been working somewhat well. :-)

@mkrupcale mkrupcale deleted the bench-stdcpp branch April 28, 2018 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants