diff options
author | Jean Boussier <[email protected]> | 2022-07-21 17:08:51 +0200 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2022-07-25 14:18:52 +0200 |
commit | 31a5586d1e007d04cfa10548d9bfb42b2787a7a0 (patch) | |
tree | 7ae8c10f44aacc03105e21fa20b132c9cecc89f7 /string.c | |
parent | f61dd38e5c85abc8c403851b1cbc3d3b04b67dbb (diff) |
rb_str_buf_append: add a fast path for ENC_CODERANGE_VALID
If the RHS has valid encoding, and both strings have the same
encoding, we can use the fast path.
However we need to update the LHS coderange.
```
compare-ruby: ruby 3.2.0dev (2022-07-21T14:46:32Z master cdbb9b8555) [arm64-darwin21]
built-ruby: ruby 3.2.0dev (2022-07-25T07:25:41Z string-concat-vali.. 11a2772bdd) [arm64-darwin21]
warming up...
| |compare-ruby|built-ruby|
|:-------------------|-----------:|---------:|
|binary_concat_7bit | 554.816k| 556.460k|
| | -| 1.00x|
|utf8_concat_7bit | 556.367k| 555.101k|
| | 1.00x| -|
|utf8_concat_UTF8 | 412.555k| 556.824k|
| | -| 1.35x|
```
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6163
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 21 |
1 files changed, 18 insertions, 3 deletions
@@ -3329,9 +3329,24 @@ VALUE rb_str_buf_append(VALUE str, VALUE str2) { int str2_cr = rb_enc_str_coderange(str2); - if (str2_cr == ENC_CODERANGE_7BIT && str_enc_fastpath(str)) { - str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true); - return str; + + if (str_enc_fastpath(str)) { + switch (str2_cr) { + case ENC_CODERANGE_7BIT: + // If RHS is 7bit we can do simple concatenation + str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true); + return str; + case ENC_CODERANGE_VALID: + // If RHS is valid, we can do simple concatenation if encodings are the same + if (ENCODING_GET_INLINED(str) == ENCODING_GET_INLINED(str2)) { + str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true); + int str_cr = ENC_CODERANGE(str); + if (UNLIKELY(str_cr != ENC_CODERANGE_VALID)) { + ENC_CODERANGE_SET(str, RB_ENC_CODERANGE_AND(str_cr, str2_cr)); + } + return str; + } + } } rb_enc_cr_str_buf_cat(str, RSTRING_PTR(str2), RSTRING_LEN(str2), |