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|
```
This commit is contained in:
Jean Boussier 2022-07-06 12:31:54 +02:00
parent 9641f23316
commit 906f7cb3e7
Notes: git 2022-07-07 00:26:24 +09:00
2 changed files with 18 additions and 1 deletions

View File

@ -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

View File

@ -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)) {