Project

General

Profile

Feature #10329 » 0002-optimize-foo-literal-string.patch

normalperson (Eric Wong), 10/06/2014 02:31 AM

View differences:

benchmark/bm_vm2_streq1.rb
i = 0
foo = "literal"
while i<6_000_000 # benchmark loop 2
i += 1
foo == "literal"
end
compile.c
}
break;
}
if (node->nd_mid == idEq && !private_recv_p(node) && node->nd_args &&
nd_type(node->nd_args) == NODE_ARRAY &&
node->nd_args->nd_alen == 1)
{
/* optimization shortcut
* obj == "literal" -> opt_streq1(obj, "literal")
*/
if (nd_type(node->nd_args->nd_head) == NODE_STR) {
VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
node->nd_args->nd_head->nd_lit = str;
COMPILE(ret, "recv", node->nd_recv);
ADD_INSN2(ret, line, opt_streq1,
new_callinfo(iseq, node->nd_mid, 1, 0, 0), str);
if (poped) {
ADD_INSN(ret, line, pop);
}
break;
}
/* TODO: optimization shortcut
* "yoda" == other -> opt_streq2("yoda", other)
*/
}
case NODE_FCALL:
case NODE_VCALL:{ /* VCALL: variable or call */
/*
insns.def
/**
@c optimize
@e recv == "literal string"
*/
DEFINE_INSN
opt_streq1
(CALL_INFO ci, VALUE lit)
(VALUE recv)
(VALUE val)
{
if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cString &&
BASIC_OP_UNREDEFINED_P(BOP_EQ, STRING_REDEFINED_OP_FLAG)) {
val = rb_str_equal(recv, lit);
}
else {
PUSH(recv);
PUSH(rb_str_resurrect(lit));
CALL_SIMPLE_METHOD(recv);
}
}
/**
@c optimize
@e optimized length
@j 最適化された recv.length()。
*/
test/ruby/test_string.rb
assert_equal before + nr, GC.stat(:total_allocated_objects)
end
end
def test_opt_streq1
assert_separately([], <<-RUBY)
class String
undef ==
def ==(str)
:TROO
end
end
assert_equal(:TROO, ("foo" == "foo"))
RUBY
if @cls == String
nr = 10
recv = "something"
res = []
before = GC.stat(:total_allocated_objects)
nr.times { res << (recv == "constant") }
assert_equal before, GC.stat(:total_allocated_objects)
assert_equal [ false ], res.uniq!
res.clear
before = GC.stat(:total_allocated_objects)
nr.times { res << (recv == "something") }
assert_equal before, GC.stat(:total_allocated_objects)
assert_equal [ true ], res.uniq!
end
end
end
class TestString2 < TestString
-
    (1-1/1)