diff options
author | Jean Boussier <[email protected]> | 2025-02-24 11:39:00 +0100 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2025-02-24 18:32:46 +0100 |
commit | 87f9c3c65e38fa3e5c6ef097e2cf63ff448f48d6 (patch) | |
tree | 511d0e2492dad3ec4f140ee4728abe4d8fa4c45c /internal/re.h | |
parent | 21ac0a3a640a2a86e8716675f82221f178e29088 (diff) |
String#gsub! Elide MatchData allocation when we know it can't escape
In gsub is used with a string replacement or a map that doesn't
have a default proc, we know for sure no code can cause the MatchData
to escape the `gsub` call.
In such case, we still have to allocate a new MatchData because we
don't know what is the lifetime of the backref, but for any subsequent
match we can re-use the MatchData we allocated ourselves, reducing
allocations significantly.
This partially fixes [Misc #20652], except when a block is used,
and partially reduce the performance impact of
abc0304cb28cb9dcc3476993bc487884c139fd11 / [Bug #17507]
```
compare-ruby: ruby 3.5.0dev (2025-02-24T09:44:57Z master 5cf146399f) +PRISM [arm64-darwin24]
built-ruby: ruby 3.5.0dev (2025-02-24T10:58:27Z gsub-elude-match da966636e9) +PRISM [arm64-darwin24]
warming up....
| |compare-ruby|built-ruby|
|:----------------|-----------:|---------:|
|escape | 3.577k| 3.697k|
| | -| 1.03x|
|escape_bin | 5.869k| 6.743k|
| | -| 1.15x|
|escape_utf8 | 3.448k| 3.738k|
| | -| 1.08x|
|escape_utf8_bin | 6.361k| 7.267k|
| | -| 1.14x|
```
Co-Authored-By: Étienne Barrié <[email protected]>
Diffstat (limited to 'internal/re.h')
-rw-r--r-- | internal/re.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/internal/re.h b/internal/re.h index 3e20114665..2788f8b42a 100644 --- a/internal/re.h +++ b/internal/re.h @@ -14,12 +14,12 @@ /* re.c */ VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline); VALUE rb_reg_check_preprocess(VALUE); -long rb_reg_search0(VALUE, VALUE, long, int, int); +long rb_reg_search0(VALUE, VALUE, long, int, int, VALUE *); VALUE rb_reg_match_p(VALUE re, VALUE str, long pos); bool rb_reg_start_with_p(VALUE re, VALUE str); VALUE rb_reg_hash(VALUE re); VALUE rb_reg_equal(VALUE re1, VALUE re2); -void rb_backref_set_string(VALUE string, long pos, long len); +VALUE rb_backref_set_string(VALUE string, long pos, long len); void rb_match_unbusy(VALUE); int rb_match_count(VALUE match); VALUE rb_reg_new_ary(VALUE ary, int options); |