Project

General

Profile

Feature #12025

Updated by naruse (Yui NARUSE) about 8 years ago

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.

Back