Details

    • Type: Bug Bug
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: JRuby 1.6.3
    • Fix Version/s: JRuby 1.7.0.pre1
    • Component/s: Performance
    • Labels:
      None
    • Environment:
      OSX, json gem version 1.6.1
    • Number of attachments :
      0

      Description

      MRI with the json gem (plus C extension) is about 2x faster than JRuby for encoding and 2.5x faster for decoding. I believe the JRuby json gem has a native java extension, so performance should be comparable.

      The gist contains the benchmark code and the output for both MRI & JRuby.

      https://gist.github.com/1374478

        Activity

        Hide
        Charles Oliver Nutter added a comment -

        I pushed a fix for Fixnum#to_s logic, avoiding the pass through a Java String, which brings the fast_generate part almost up to 1.9.3 speed. The remaining overhead is probably in json itself.

        https://github.com/jruby/jruby/commit/3efcf88b5e50bf86c816a2e6488480968b6210e9

        The parse benchmark, as I'd expect, is also slow because of passing through Java String logic. Specifically, we use Long.valueOf() to do our parsing, and then convert that into ISO-8859-1 characters. That will be a more complicated fix.

        Show
        Charles Oliver Nutter added a comment - I pushed a fix for Fixnum#to_s logic, avoiding the pass through a Java String, which brings the fast_generate part almost up to 1.9.3 speed. The remaining overhead is probably in json itself. https://github.com/jruby/jruby/commit/3efcf88b5e50bf86c816a2e6488480968b6210e9 The parse benchmark, as I'd expect, is also slow because of passing through Java String logic. Specifically, we use Long.valueOf() to do our parsing, and then convert that into ISO-8859-1 characters. That will be a more complicated fix.
        Hide
        Charles Oliver Nutter added a comment -

        More tweakage...

        • I submitted a pull request to json for a few minor performance tweaks. https://github.com/flori/json/pull/112
        • I tweaked ByteList to be a bit cheaper for a constructor that was supposed to wrap but copied.

        Not quite as fast as 1.9.3 yet, but getting there:

        jruby:
        parse:                   2.968000   0.000000   2.968000 (  2.968000)
        
        1.9.3:
        parse:                    1.830000   0.000000   1.830000 (  1.833186)
        
        Show
        Charles Oliver Nutter added a comment - More tweakage... I submitted a pull request to json for a few minor performance tweaks. https://github.com/flori/json/pull/112 I tweaked ByteList to be a bit cheaper for a constructor that was supposed to wrap but copied. Not quite as fast as 1.9.3 yet, but getting there: jruby: parse: 2.968000 0.000000 2.968000 ( 2.968000) 1.9.3: parse: 1.830000 0.000000 1.830000 ( 1.833186)
        Hide
        Charles Oliver Nutter added a comment -

        So after all my tweaks to JRuby and json, here's where we stand:

        JRuby master, Java 7u2
        
        fast generate:           1.032000   0.000000   1.032000 (  1.032000)
        pack:                    0.198000   0.000000   0.198000 (  0.198000)
        parse:                   2.936000   0.000000   2.936000 (  2.936000)
        unpack:                  0.195000   0.000000   0.195000 (  0.195000)
        
        Ruby 1.9.3
        
        fast generate:            0.910000   0.010000   0.920000 (  0.915610)
        pack:                     0.370000   0.000000   0.370000 (  0.369670)
        parse:                    1.800000   0.000000   1.800000 (  1.795662)
        unpack:                   0.250000   0.000000   0.250000 (  0.249210)
        
        RBX master
        
        fast generate:           1.851710   0.004018   1.855728 (  1.855763)
        pack:                    0.222840   0.000049   0.222889 (  0.222896)
        parse:                   1.426398   0.002595   1.428993 (  1.429054)
        unpack:                  0.312026   0.000078   0.312104 (  0.312091)
        

        Obviously pack and unpack are doing well. fast_generate is nearly there, only about 11% off of MRI's time. parse is further off, around 60% slower. So we're not entirely there yet, but it's much better. Also, my parser fixes for json will have eliminated massive amounts of object creation, which can kill concurrent performance.

        When I profile parse now, the top hot spots are all in Ragel-generated code, so there may not be much I can do to improve it further. This may be an issue with Ragel on JVM.

        Show
        Charles Oliver Nutter added a comment - So after all my tweaks to JRuby and json, here's where we stand: JRuby master, Java 7u2 fast generate: 1.032000 0.000000 1.032000 ( 1.032000) pack: 0.198000 0.000000 0.198000 ( 0.198000) parse: 2.936000 0.000000 2.936000 ( 2.936000) unpack: 0.195000 0.000000 0.195000 ( 0.195000) Ruby 1.9.3 fast generate: 0.910000 0.010000 0.920000 ( 0.915610) pack: 0.370000 0.000000 0.370000 ( 0.369670) parse: 1.800000 0.000000 1.800000 ( 1.795662) unpack: 0.250000 0.000000 0.250000 ( 0.249210) RBX master fast generate: 1.851710 0.004018 1.855728 ( 1.855763) pack: 0.222840 0.000049 0.222889 ( 0.222896) parse: 1.426398 0.002595 1.428993 ( 1.429054) unpack: 0.312026 0.000078 0.312104 ( 0.312091) Obviously pack and unpack are doing well. fast_generate is nearly there, only about 11% off of MRI's time. parse is further off, around 60% slower. So we're not entirely there yet, but it's much better. Also, my parser fixes for json will have eliminated massive amounts of object creation, which can kill concurrent performance. When I profile parse now, the top hot spots are all in Ragel-generated code, so there may not be much I can do to improve it further. This may be an issue with Ragel on JVM.
        Hide
        Charles Oliver Nutter added a comment -

        I've started a thread on the Ragel list asking what it would take to get the faster FSM forms working on JVM. They mostly depend on 'goto', so I'm proposing a few ways to make that happen.

        Outside speeding up Ragel, I'm not sure there's much more we can do here, so I'm marking this resolved. We're no longer 2x slower, we're between 1.1x and 1.6x slower

        Show
        Charles Oliver Nutter added a comment - I've started a thread on the Ragel list asking what it would take to get the faster FSM forms working on JVM. They mostly depend on 'goto', so I'm proposing a few ways to make that happen. Outside speeding up Ragel, I'm not sure there's much more we can do here, so I'm marking this resolved. We're no longer 2x slower, we're between 1.1x and 1.6x slower
        Hide
        Chuck Remes added a comment -

        Charlie, great work! I very much appreciate the performance improvements that you made.

        I'll watch the ragel list to see if there are any suggestions. I was a member of that list long ago but traffic is quite low. I think the author is satisfied with the state of things (pun intended), so improvements to the fsm generators will need to catch the eye of a Java guru. If the New Year is good to me I'll look at offering a bounty to improve the Java generator.

        Show
        Chuck Remes added a comment - Charlie, great work! I very much appreciate the performance improvements that you made. I'll watch the ragel list to see if there are any suggestions. I was a member of that list long ago but traffic is quite low. I think the author is satisfied with the state of things (pun intended), so improvements to the fsm generators will need to catch the eye of a Java guru. If the New Year is good to me I'll look at offering a bounty to improve the Java generator.

          People

          • Assignee:
            Charles Oliver Nutter
            Reporter:
            Chuck Remes
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: