[ruby-core:70105] Re: [Ruby trunk - Feature #11375] Decreased Object Allocation in Pathname.rb

From: Eric Wong <normalperson@...>
Date: 2015-07-23 19:55:10 UTC
List: ruby-core #70105
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.

In This Thread