From cb9fd920a31c8090fae0b1183be9483e17dc3e96 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 19 Jul 2022 09:13:19 +0200 Subject: [PATCH] str_buf_cat: preserve coderange when going through fastpath rb_str_modify clear the coderange, which in this case isn't necessary. ``` compare-ruby: ruby 3.2.0dev (2022-07-12T15:01:11Z master 71aec68566) [arm64-darwin21] built-ruby: ruby 3.2.0dev (2022-07-19T07:17:01Z faster-buffer-conc.. 3cad62aab4) [arm64-darwin21] warming up... | |compare-ruby|built-ruby| |:---------------------|-----------:|---------:| |binary_concat_utf8 | 360.617k| 605.091k| | | -| 1.68x| |binary_concat_binary | 446.650k| 605.053k| | | -| 1.35x| |utf8_concat_utf8 | 454.166k| 597.311k| | | -| 1.32x| ``` ``` | |compare-ruby|built-ruby| |:-----------|-----------:|---------:| |erb_render | 1.790M| 2.045M| | | -| 1.14x| ``` --- string.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/string.c b/string.c index d6c79c7988..8f519da7d1 100644 --- a/string.c +++ b/string.c @@ -3110,8 +3110,16 @@ rb_str_resize(VALUE str, long len) } static VALUE -str_buf_cat(VALUE str, const char *ptr, long len) +str_buf_cat4(VALUE str, const char *ptr, long len, bool keep_cr) { + if (keep_cr) { + str_modify_keep_cr(str); + } + else { + rb_str_modify(str); + } + if (len == 0) return 0; + long capa, total, olen, off = -1; char *sptr; const int termlen = TERM_LEN(str); @@ -3123,12 +3131,11 @@ str_buf_cat(VALUE str, const char *ptr, long len) if (ptr >= sptr && ptr <= sptr + olen) { off = ptr - sptr; } - rb_str_modify(str); - if (len == 0) return 0; + if (STR_EMBED_P(str)) { capa = str_embed_capa(str) - termlen; sptr = RSTRING(str)->as.embed.ary; - olen = RSTRING_EMBED_LEN(str); + olen = RSTRING_EMBED_LEN(str); } else { capa = RSTRING(str)->as.heap.aux.capa; @@ -3159,7 +3166,8 @@ str_buf_cat(VALUE str, const char *ptr, long len) return str; } -#define str_buf_cat2(str, ptr) str_buf_cat((str), (ptr), rb_strlen_lit(ptr)) +#define str_buf_cat(str, ptr, len) str_buf_cat4((str), (ptr), len, false) +#define str_buf_cat2(str, ptr) str_buf_cat4((str), (ptr), rb_strlen_lit(ptr), false) VALUE rb_str_cat(VALUE str, const char *ptr, long len) @@ -3322,7 +3330,7 @@ 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_cat(str, RSTRING_PTR(str2), RSTRING_LEN(str2)); + str_buf_cat4(str, RSTRING_PTR(str2), RSTRING_LEN(str2), true); return str; }