diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-08-17 16:34:40 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-08-17 16:34:40 +0000 |
commit | d067b263c7d0ea0995992cefa8145e16e3b9e920 (patch) | |
tree | 09feb3983e7a99211ac4221558ad9e8cd474b225 /string.c | |
parent | 0db193f98d97d235e7628815b2ba64dc530be2e6 (diff) |
Add optimization for creating zerofill string
```
require 'benchmark'
n = 1 * 1024 * 1024 * 1024
Benchmark.bmbm do |x|
x.report("*") { 0.chr * n }
x.report("ljust") { String.new(capacity: n).ljust(n, "\0") }
end
```
Before
```% ./ruby test.rb
Rehearsal -----------------------------------------
* 0.358396 0.392753 0.751149 ( 1.134231)
ljust 0.203277 0.389223 0.592500 ( 0.594816)
-------------------------------- total: 1.343649sec
user system total real
* 0.282647 0.304600 0.587247 ( 0.589205)
ljust 0.201834 0.283801 0.485635 ( 0.487617)
```
After
```% ./ruby test.rb
Rehearsal -----------------------------------------
* 0.000522 0.000021 0.000543 ( 0.000534)
ljust 0.208551 0.321030 0.529581 ( 0.542083)
-------------------------------- total: 0.530124sec
user system total real
* 0.000069 0.000006 0.000075 ( 0.000069)
ljust 0.206698 0.301032 0.507730 ( 0.517674)
```
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59614 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r-- | string.c | 12 |
1 files changed, 12 insertions, 0 deletions
@@ -1905,6 +1905,18 @@ rb_str_times(VALUE str, VALUE times) if (len < 0) { rb_raise(rb_eArgError, "negative argument"); } + if (RSTRING_LEN(str) == 1 && RSTRING_PTR(str)[0] == 0) { + str2 = str_alloc(rb_obj_class(str)); + if (!STR_EMBEDDABLE_P(len, 1)) { + RSTRING(str2)->as.heap.aux.capa = len; + RSTRING(str2)->as.heap.ptr = ZALLOC_N(char, (size_t)len + 1); + STR_SET_NOEMBED(str2); + } + STR_SET_LEN(str2, len); + rb_enc_copy(str2, str); + OBJ_INFECT(str2, str); + return str2; + } if (len && LONG_MAX/len < RSTRING_LEN(str)) { rb_raise(rb_eArgError, "argument too big"); } |