ruby-changes:39889
From: nobu <ko1@a...>
Date: Tue, 29 Sep 2015 16:39:07 +0900 (JST)
Subject: [ruby-changes:39889] nobu:r51970 (trunk): compile.c: fix performance of strconcat
nobu 2015-09-29 16:37:40 +0900 (Tue, 29 Sep 2015) New Revision: 51970 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51970 Log: compile.c: fix performance of strconcat * compile.c (compile_dstr_fragments): fix performance by omitting the first empty string only for keeping literal encoding if other literals are too. [ruby-core:70930] [Bug #11556] * string.c (rb_str_append_literal): append but keep encoding non US-ASCII. Modified files: trunk/ChangeLog trunk/compile.c trunk/insns.def trunk/string.c trunk/vm.c Index: insns.def =================================================================== --- insns.def (revision 51969) +++ insns.def (revision 51970) @@ -370,7 +370,7 @@ concatstrings https://github.com/ruby/ruby/blob/trunk/insns.def#L370 val = rb_str_resurrect(TOPN(i)); while (i-- > 0) { const VALUE v = TOPN(i); - rb_str_append(val, v); + rb_str_append_literal(val, v); } POPN(num); } Index: ChangeLog =================================================================== --- ChangeLog (revision 51969) +++ ChangeLog (revision 51970) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Sep 29 16:37:29 2015 Nobuyoshi Nakada <nobu@r...> + + * compile.c (compile_dstr_fragments): fix performance by omitting + the first empty string only for keeping literal encoding if + other literals are too. [ruby-core:70930] [Bug #11556] + + * string.c (rb_str_append_literal): append but keep encoding non + US-ASCII. + Mon Sep 28 17:40:17 2015 Shugo Maeda <shugo@r...> * lib/net/ftp.rb (mtime): use usec instead of fractions to parse Index: string.c =================================================================== --- string.c (revision 51969) +++ string.c (revision 51970) @@ -2460,6 +2460,18 @@ rb_str_append(VALUE str, VALUE str2) https://github.com/ruby/ruby/blob/trunk/string.c#L2460 return rb_str_buf_append(str, str2); } +VALUE +rb_str_append_literal(VALUE str, VALUE str2) +{ + int encidx = rb_enc_get_index(str2); + rb_str_buf_append(str, str2); + if (encidx != ENCINDEX_US_ASCII) { + if (rb_enc_get_index(str) == ENCINDEX_US_ASCII) + rb_enc_associate_index(str, encidx); + } + return str; +} + /* * call-seq: * str << integer -> str Index: compile.c =================================================================== --- compile.c (revision 51969) +++ compile.c (revision 51970) @@ -788,6 +788,12 @@ FIRST_ELEMENT(LINK_ANCHOR *anchor) https://github.com/ruby/ruby/blob/trunk/compile.c#L788 } static LINK_ELEMENT * +LAST_ELEMENT(LINK_ANCHOR *anchor) +{ + return anchor->last; +} + +static LINK_ELEMENT * POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor) { LINK_ELEMENT *elem = anchor->last; @@ -2329,6 +2335,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2335 { NODE *list = node->nd_next; VALUE lit = node->nd_lit; + LINK_ELEMENT *first_lit = 0; int cnt = 0; debugp_param("nd_lit", lit); @@ -2337,6 +2344,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2344 if (RB_TYPE_P(lit, T_STRING)) lit = node->nd_lit = rb_fstring(node->nd_lit); ADD_INSN1(ret, nd_line(node), putobject, lit); + if (RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret); } while (list) { @@ -2344,6 +2352,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2352 if (nd_type(node) == NODE_STR) { node->nd_lit = rb_fstring(node->nd_lit); ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit); + lit = Qnil; } else { COMPILE(ret, "each string", node); @@ -2351,6 +2360,10 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2360 cnt++; list = list->nd_next; } + if (NIL_P(lit) && first_lit) { + REMOVE_ELEM(first_lit); + --cnt; + } *cntp = cnt; return COMPILE_OK; Index: vm.c =================================================================== --- vm.c (revision 51969) +++ vm.c (revision 51970) @@ -21,6 +21,8 @@ https://github.com/ruby/ruby/blob/trunk/vm.c#L21 #include "probes.h" #include "probes_helper.h" +VALUE rb_str_append_literal(VALUE str, VALUE str2); + static inline VALUE * VM_EP_LEP(VALUE *ep) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/