Skip to content

faster unpack1#5928

Merged
enebo merged 1 commit intojruby:masterfrom
ahorek:unpack1
Oct 22, 2019
Merged

faster unpack1#5928
enebo merged 1 commit intojruby:masterfrom
ahorek:unpack1

Conversation

@ahorek
Copy link
Contributor

@ahorek ahorek commented Oct 20, 2019

feature String#unpack1 should be an optimization, but on jruby it's significantly slower even more than #unpack.first

examples from stdlib

str.unpack1("m")

sprintf("%%%02X", m.unpack1("C"))

jruby
           unpack h*      2.961M (? 4.8%) i/s -     14.738M in   4.995894s
          unpack1 h*    591.196k (? 8.0%) i/s -      2.946M in   5.019534s
           unpack C*      2.628M (? 5.9%) i/s -     13.082M in   5.000418s
          unpack1 C*    642.124k (? 3.2%) i/s -      3.227M in   5.032145s
            unpack m      2.878M (? 5.8%) i/s -     14.328M in   5.002753s
           unpack1 m    616.794k (? 2.4%) i/s -      3.095M in   5.020186s
        unpack block    542.986k (? 7.7%) i/s -      2.697M in   5.004756s
       unpack1 block    522.406k (? 3.7%) i/s -      2.623M in   5.028202s

jruby + patch
           unpack h*      2.904M (? 5.3%) i/s -     14.453M in   4.994340s
          unpack1 h*      3.153M (? 4.2%) i/s -     15.747M in   5.005090s
           unpack C*      2.441M (? 5.9%) i/s -     12.199M in   5.021349s
          unpack1 C*      3.673M (? 6.2%) i/s -     18.317M in   5.011808s
            unpack m      2.821M (? 3.9%) i/s -     14.101M in   5.008559s
           unpack1 m      3.037M (? 5.6%) i/s -     15.123M in   5.007571s
        unpack block    578.569k (? 4.9%) i/s -      2.897M in   5.022202s
       unpack1 block      1.871M (? 3.6%) i/s -      9.381M in   5.021880s

ruby 2.7
           unpack h*      2.600M (±16.2%) i/s -     12.405M in   5.013330s
          unpack1 h*      3.718M (±13.1%) i/s -     18.004M in   5.000438s
           unpack C*      1.245M (±13.6%) i/s -      6.107M in   5.026846s
          unpack1 C*      4.960M (±11.6%) i/s -     24.207M in   5.001412s
            unpack m      3.125M (±14.5%) i/s -     15.193M in   4.997823s
           unpack1 m      4.479M (±13.1%) i/s -     21.788M in   4.998978s
        unpack block      2.492M (±11.5%) i/s -     12.306M in   5.015661s
       unpack1 block      3.790M (±13.4%) i/s -     18.542M in   5.010570s

truffleruby 19.0.0
           unpack h*      9.193M (±23.8%) i/s -     35.973M in   4.990790s
          unpack1 h*      8.758M (±24.5%) i/s -     31.961M in   5.010966s
           unpack C*     12.899M (±18.6%) i/s -     51.961M in   5.096628s
          unpack1 C*     13.891M (±22.1%) i/s -     49.695M in   4.995458s
            unpack m      3.773M (±17.8%) i/s -     17.240M in   5.141586s
           unpack1 m      3.725M (±20.4%) i/s -     15.927M in   5.029317s
        unpack block      4.120M (±28.6%) i/s -     15.636M in   5.007153s
       unpack1 block      8.467M (±20.2%) i/s -     33.450M in   5.004004s
require 'base64'
require 'benchmark/ips'

STRING = "foobarbaz".freeze

def unpack_block
  STRING.unpack('b5B8') { |x| return x }
end

def unpack1_block
  STRING.unpack1('b5B8') { |x| return x }
end

Benchmark.ips do |x|
  x.report('unpack h*') { STRING.unpack('h*').first }
  x.report('unpack1 h*') { STRING.unpack1('h*') }
  x.report('unpack C*') { STRING.unpack("C*").first }
  x.report('unpack1 C*') { STRING.unpack1("C*") }
  x.report('unpack m') { STRING.unpack("m").first }
  x.report('unpack1 m') { STRING.unpack1("m") }
  x.report('unpack block') { unpack_block }
  x.report('unpack1 block') { unpack1_block }
end

@kares
Copy link
Member

kares commented Oct 21, 2019

very nice! jruby still slower than MRI - did you happen to find out where time is being spent?

@enebo enebo added this to the JRuby 9.2.9.0 milestone Oct 22, 2019
@enebo enebo merged commit 806fc01 into jruby:master Oct 22, 2019
headius added a commit that referenced this pull request Oct 23, 2019
Additional optimization on top of #5928.
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