Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliminate transient objects for looking up symbol by bytelist #5512

Merged
merged 1 commit into from Dec 13, 2018

Conversation

Projects
None yet
3 participants
@headius
Copy link
Member

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[]
...
Eliminate transient objects for looking up symbol by bytelist.
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 Dec 13, 2018

@kares

kares approved these changes Dec 13, 2018

Copy link
Member

left a comment

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

@headius

This comment has been minimized.

Copy link
Member Author

commented Dec 13, 2018

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

@enebo

enebo approved these changes Dec 13, 2018

@headius

This comment has been minimized.

Copy link
Member Author

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

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details

@headius headius deleted the headius:direct_string_hashcode branch Dec 13, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.