Skip to content

Eliminate transient objects for looking up symbol by bytelist#5512

Merged
headius merged 1 commit intojruby:masterfrom
headius:direct_string_hashcode
Dec 13, 2018
Merged

Eliminate transient objects for looking up symbol by bytelist#5512
headius merged 1 commit intojruby:masterfrom
headius:direct_string_hashcode

Conversation

@headius
Copy link
Member

@headius headius commented Dec 12, 2018

The old logic constructed an intermediate java.lang.String and
called hashCode, which in turn created an ISO8859_1 decoder and
buffers to do the decoding. This showed up in heap profiles of the
state_machine library, but would generically affect any case where
a Ruby String was used to retrieve a Ruby Symbol.

The logic here should match what an ISO8859_1 Java String would
do. The accompanying tests makes sure this is so.

For the profiled run in question, the only ISO8859_1 decoders in the process were created by the old logic:

          percent          live          alloc'ed  stack class
 rank   self  accum     bytes objs     bytes  objs trace name
    1  3.35%  3.35%   4555392 94904  38400480 800010 422602 char[]
    2  2.84%  6.18%   3863800 96595  34070960 851774 327174 sun.nio.cs.ISO_8859_1$Decoder
    3  2.09%  8.27%   2847120 71178  23995240 599881 424712 org.jruby.RubyString
    4  1.67%  9.95%   2277696 94904  19200240 800010 422601 java.lang.String
    5  1.39% 11.34%   1898080 47452  15990000 399750 424724 org.jruby.RubyHash$RubyHashEntry
    6  1.03% 12.37%   1403040 87690   5635392 352212 411554 org.jruby.runtime.builtin.IRubyObject[]
...

The old logic constructed an intermediate java.lang.String and
called hashCode, which in turn created an ISO8859_1 decoder and
buffers to do the decoding. This showed up in heap profiles of the
state_machine library, but would generically affect any case where
a Ruby String was used to retrieve a Ruby Symbol.

The logic here should match what an ISO8859_1 Java String would
do. The accompanying tests makes sure this is so.
@headius headius added this to the JRuby 9.2.6.0 milestone Dec 12, 2018
@headius headius requested review from enebo and kares December 13, 2018 00:11
Copy link
Member

@kares kares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 ... guess String hashCode is standardized
guaranteed to be the same across JVMs, since otherwise case(str) byte-code would break

@headius
Copy link
Member Author

headius commented Dec 13, 2018

@kares Yes, Java's String hashcode calculation is set in stone (i.e. in the spec).

@headius
Copy link
Member Author

headius commented Dec 13, 2018

Good improvement from this...here's before and after:

[] ~/projects/jruby $ jruby -e 'str = "foooo"; loop { t = Time.now; i = 0; while i < 10_000_000; i+=1; str.intern; str.intern; str.intern; str.intern; str.intern; end; puts Time.now - t }'
3.370897
3.080245
3.0544759999999997
3.065854

[] ~/projects/jruby $ jruby -e 'str = "foooo"; loop { t = Time.now; i = 0; while i < 10_000_000; i+=1; str.intern; str.intern; str.intern; str.intern; str.intern; end; puts Time.now - t }'
1.471295
1.331397
1.265666
1.269925

@headius headius merged commit a0c8853 into jruby:master Dec 13, 2018
@headius headius deleted the direct_string_hashcode branch December 13, 2018 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants