[前][次][番号順一覧][スレッド一覧]

ruby-changes:47498

From: naruse <ko1@a...>
Date: Fri, 18 Aug 2017 01:34:46 +0900 (JST)
Subject: [ruby-changes:47498] naruse:r59614 (trunk): Add optimization for creating zerofill string

naruse	2017-08-18 01:34:40 +0900 (Fri, 18 Aug 2017)

  New Revision: 59614

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59614

  Log:
    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)
    ```

  Modified files:
    trunk/string.c
Index: string.c
===================================================================
--- string.c	(revision 59613)
+++ string.c	(revision 59614)
@@ -1905,6 +1905,18 @@ rb_str_times(VALUE str, VALUE times) https://github.com/ruby/ruby/blob/trunk/string.c#L1905
     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");
     }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]