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

JRuby support #21

Merged
merged 1 commit into from Jul 20, 2020
Merged

JRuby support #21

merged 1 commit into from Jul 20, 2020

Conversation

headius
Copy link
Contributor

@headius headius commented Nov 13, 2017

This PR tracks JRuby support.

I ran into this library in use by Mastodon. Unfortunately, there's no JRuby version.

After looking at the codebase it was obvious this was a 10 minute job. Naturally, it took me 30 minutes. But here it is.

I have not included any logic to build the jar. We could use one of the JRuby-friendly compile plugins for Rake, or just script the simple process:

$ cd ext/java/

$ javac -cp ../../../jruby/lib/jruby.jar fast_blank.java

$ jar cvf ../../lib/fast_blank.jar fast_blank.class
added manifest
adding: fast_blank.class(in = 2182) (out= 1121)(deflated 48%)

$ cd ../..

$ jruby -Ilib -e 'require "fast_blank"; p "".blank?'
true

@SamSaffron
Copy link
Owner

Thanks heaps @headius

Do you mind adding this to .travis so CI runs it and making sure bundle exec rake release is still operational (publishes jruby and ruby gems)

@SamSaffron
Copy link
Owner

Taking a step back here, do we even need this micro-optimisation in jruby? in cruby the implementation 2-10x faster but in JRuby, who knows. Maybe simplest is just to tell this to use a Ruby implementation in JRuby which makes distribution easier

@headius
Copy link
Contributor Author

headius commented Nov 20, 2017

@SamSaffron Yeah that's a good point, let me do some investigation.

@headius
Copy link
Contributor Author

headius commented Nov 20, 2017

Ok...so we certainly run these things faster than MRI, but not as fast as the native implementation currently.

I also added a "medium_blank?" using String#strip, which is faster than the regex version but still a bit slower than native (and I'm not sure it's equivalent):

length 0:
Comparison:
          Fast Blank: 60381369.0 i/s
  Fast ActiveSupport: 56857156.7 i/s - same-ish: difference falls within error
      New Slow Blank: 31188957.7 i/s - 1.94x  slower
        Medium Blank: 16125828.1 i/s - 3.74x  slower
          Slow Blank:  4810642.2 i/s - 12.55x  slower

length 136:
Comparison:
  Fast ActiveSupport: 19512980.6 i/s
          Fast Blank: 18616463.9 i/s - same-ish: difference falls within error
        Medium Blank: 13891669.9 i/s - 1.40x  slower
      New Slow Blank:  3878200.6 i/s - 5.03x  slower
          Slow Blank:  3095410.6 i/s - 6.30x  slower

Compared with MRI 2.4.1:

length 0:
Comparison:
  Fast ActiveSupport: 31278034.7 i/s
          Fast Blank: 29825601.3 i/s - same-ish: difference falls within error
      New Slow Blank: 28435103.3 i/s - same-ish: difference falls within error
        Medium Blank: 11616093.6 i/s - 2.69x  slower
          Slow Blank:  1267613.4 i/s - 24.67x  slower

length 136:
Comparison:
  Fast ActiveSupport: 16889991.9 i/s
          Fast Blank: 16679032.1 i/s - same-ish: difference falls within error
        Medium Blank:  7152565.5 i/s - 2.36x  slower
          Slow Blank:  2650670.4 i/s - 6.37x  slower
      New Slow Blank:  1298571.0 i/s - 13.01x  slower

So every case is faster than MRI (which isn't really surprising). However, the biggest thing fast_blank does for all of these impls is eliminate all the garbage created by the pure-Ruby versions.

A short term fix would be to release a jruby version of the gem that just uses the fastest valid Ruby impl. It could either be a java platform version of the gem, or I believe the ext building script (Rakefile in this case) could just short-circuit and do nothing when on JRuby. Then we just need to detect 'java' platform and load the pure-Ruby version.

However, we'd still get the best perf out of an ext, unfortunately.

This commit has no build smarts. Here's the process:

```
$ javac -cp ../jruby/lib/jruby.jar -d ext/java ext/java/com/headius/jruby/fast_blank/FastBlankLibrary.java

$ jar cvf lib/fast_blank.jar -C ext/java/ com

$ jruby -Ilib -e 'require "fast_blank"; p "".blank?'
true
```

Proper support will use `rake-compiler` to build the jar.
@headius
Copy link
Contributor Author

headius commented Jul 18, 2020

I've pushed an update to this in an effort to get it out of my queue... this gem still does not install on JRuby, so having pretty much anything would be better than that.

Updated performance comparison with CRuby 2.7:

JRuby:

Length: 0
          Fast Blank     94.581M (± 4.7%) i/s -    475.212M in   5.038155s
  Fast ActiveSupport     95.359M (± 2.1%) i/s -    483.944M in   5.077346s
          Slow Blank      8.296M (± 3.6%) i/s -     41.769M in   5.041822s
      New Slow Blank     69.993M (± 3.8%) i/s -    353.460M in   5.058077s

Length: 136
          Fast Blank     30.085M (± 1.9%) i/s -    150.647M in   5.009261s
  Fast ActiveSupport     30.424M (± 6.1%) i/s -    151.429M in   5.003379s
          Slow Blank      5.477M (± 2.9%) i/s -     27.889M in   5.095904s
      New Slow Blank      6.785M (± 3.8%) i/s -     34.394M in   5.076917s

CRuby:

Length: 0
          Fast Blank     26.078M (± 1.2%) i/s -    132.360M in   5.076253s
  Fast ActiveSupport     25.924M (± 1.4%) i/s -    130.781M in   5.045730s
          Slow Blank      1.141M (± 3.3%) i/s -      5.797M in   5.084626s
      New Slow Blank     28.273M (± 3.2%) i/s -    143.628M in   5.085838s

Length: 136
          Fast Blank     14.281M (± 3.6%) i/s -     72.022M in   5.050024s
  Fast ActiveSupport     15.529M (± 2.4%) i/s -     77.682M in   5.005593s
          Slow Blank      2.656M (± 2.3%) i/s -     13.419M in   5.055645s
      New Slow Blank      1.152M (± 6.1%) i/s -      5.842M in   5.094021s

@SamSaffron
Copy link
Owner

I am fine with this, but we need to redo the gemspec and add instructions on how to publish the jruby version.

@SamSaffron SamSaffron merged commit 1d81e20 into SamSaffron:master Jul 20, 2020
@headius headius deleted the jruby branch July 21, 2020 07:31
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.

None yet

2 participants