From 906f7cb3e7e6de2b75dc4a4a3c09f98d8bf28388 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 6 Jul 2022 12:31:54 +0200 Subject: [PATCH] vm_opt_ltlt: call rb_str_buf_append directly if RHS is a String `rb_str_concat` does a lot of type checking we can easily bypass. ``` | |compare-ruby|built-ruby| |:--------------|-----------:|---------:| |string_concat | 362.007k| 398.965k| | | -| 1.10x| ``` --- benchmark/string_concat.yml | 13 +++++++++++++ vm_insnhelper.c | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 benchmark/string_concat.yml diff --git a/benchmark/string_concat.yml b/benchmark/string_concat.yml new file mode 100644 index 00000000000000..da403e7a530dce --- /dev/null +++ b/benchmark/string_concat.yml @@ -0,0 +1,13 @@ +prelude: | + CHUNK = "a" * 64 +benchmark: + string_concat: | + buffer = String.new(capacity: 4096) + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK + buffer << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK << CHUNK diff --git a/vm_insnhelper.c b/vm_insnhelper.c index abc8aef0536bcf..8db11be5e52179 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -5376,7 +5376,11 @@ vm_opt_ltlt(VALUE recv, VALUE obj) } else if (RBASIC_CLASS(recv) == rb_cString && BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) { - return rb_str_concat(recv, obj); + if (LIKELY(RB_TYPE_P(obj, T_STRING))) { + return rb_str_buf_append(recv, obj); + } else { + return rb_str_concat(recv, obj); + } } else if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_LTLT, ARRAY_REDEFINED_OP_FLAG)) {