From: Eric Wong Date: 2015-07-23T19:55:10+00:00 Subject: [ruby-core:70105] Re: [Ruby trunk - Feature #11375] Decreased Object Allocation in Pathname.rb richard.schneeman@gmail.com wrote: > You've mentioned the case statement optimization previously in a patch I sent to Rack. I agree that the difference is pretty negligible. Although I'm able to consistently see one running `benchmark/ips` Thanks. We need to see if we can optimize case/when for smaller statements. It looks to be a problem with st_lookup (from opt_case_dispatch) being pointless for small case/when statements. Perhaps try something like the following patch to compile.c --- a/compile.c +++ b/compile.c @@ -3471,7 +3471,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel); } - if (only_special_literals) { + if (only_special_literals && RHASH_SIZE(literals) > 6) { iseq_add_mark_object(iseq, literals); ADD_INSN(ret, nd_line(tempnode), dup); Need to play around with the threshold, I chose 6 since that's when the hash actually uses hashing instead of a (redundant) linear scan. (IOW, 6 == MAX_PACKED_HASH in st.c) On your overall patch to pathname.rb, I'd like to hear what others (ko1/nobu/matz) think about it. My main concern is things like this disincentivize VM/compiler improvements and make it harder to gauge future improvements. Part of the problem with benchmarking [Feature #10423] (opt_str_lit) was there are already many cases of #freeze usage in Discourse (and unicorn :x) which made improvements to the compiler/VM ineffective. The more generic code of opt_str_lit also made slightly slower than the specialized, one-off instructions we have now, too. Anyways I'm not an architect or leader of Ruby (and have no interest in being one), so it's up to ko1/nobu/matz to decide. > I am curious in general how other languages deal with this issue. It looks > like Java http://java-performance.info/java-string-deduplication/ allocates > every string literal as a frozen string and then unfreezes when someone tries > to modify it. Like a CoW string pool? We do that since 2.1 with fstrings on pure Ruby code, at least. It doesn't help with object allocation rates and common strings <=23 bytes still get copied.