summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-14 23:30:29 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-07-14 23:30:29 +0000
commited5401a696fe284b71c015fb4974396755354a7d (patch)
treec382c44a5fd46d1ae967b9da9ca365deae6107a3
parent0fd7666d57f9919962ae28ae7a6758451e10cd11 (diff)
string.c: reduce malloc overhead for default buffer size
* string.c (STR_BUF_MIN_SIZE): reduce from 128 to 127 [ruby-core:76371] [Feature #12025] * string.c (rb_str_buf_new): adjust for above reduction From Jeremy Evans <code@jeremyevans.net>: This changes the minimum buffer size for string buffers from 128 to 127. The underlying C buffer is always 1 more than the ruby buffer, so this changes the actual amount of memory used for the minimum string buffer from 129 to 128. This makes it much easier on the malloc implementation, as evidenced by the following code (note that time -l is used here, but Linux systems may need time -v). $ cat bench_mem.rb i = ARGV.first.to_i Array.new(1000000){" " * i} $ /usr/bin/time -l ruby bench_mem.rb 128 3.10 real 2.19 user 0.46 sys 289080 maximum resident set size 72673 minor page faults 13 block output operations 29 voluntary context switches $ /usr/bin/time -l ruby bench_mem.rb 127 2.64 real 2.09 user 0.27 sys 162720 maximum resident set size 40966 minor page faults 2 block output operations 4 voluntary context switches To try to ensure a power-of-2 growth, when a ruby string capacity needs to be increased, after doubling the capacity, add one. This ensures the ruby capacity will be odd, which means actual amount of memory used will be even, which is probably better than the current case of the ruby capacity being even and the actual amount of memory used being odd. A very similar patch was proposed 4 years ago in feature #5875. It ended up being rejected, because no performance increase was shown. One reason for that is that ruby does not use STR_BUF_MIN_SIZE unless rb_str_buf_new is called, and that previously did not have a ruby API, only a C API, so unless you were using a C extension that called it, there would be no performance increase. With the recently proposed feature #12024, String.buffer is added, which is a ruby API for creating string buffers. Using String.buffer(100) wastes much less memory with this patch, as the malloc implementation can more easily deal with the power-of-2 sized memory usage. As measured above, memory usage is 44% less, and performance is 17% better. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55686 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--string.c4
2 files changed, 8 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ddd4ad666..9e378c1088 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Jul 15 08:25:15 2016 Jeremy Evans <code@jeremyevans.net>
+
+ * string.c (STR_BUF_MIN_SIZE): reduce from 128 to 127
+ [ruby-core:76371] [Feature #12025]
+ * string.c (rb_str_buf_new): adjust for above reduction
+
Thu Jul 14 17:26:00 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
* Makefile.in (enc/unicode/name2ctype.h): remove stale recipe,
diff --git a/string.c b/string.c
index ff3792ffb2..4bc4ebfd99 100644
--- a/string.c
+++ b/string.c
@@ -1188,7 +1188,7 @@ str_new_empty(VALUE str)
return v;
}
-#define STR_BUF_MIN_SIZE 128
+#define STR_BUF_MIN_SIZE 127
VALUE
rb_str_buf_new(long capa)
@@ -2590,7 +2590,7 @@ str_buf_cat(VALUE str, const char *ptr, long len)
capa = (total + 4095) / 4096 * 4096;
break;
}
- capa = 2 * capa;
+ capa = 2 * capa + 1;
}
}
else {