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

aligned (and faster) uniq impls + less wrapping #5830

Merged
merged 7 commits into from Aug 14, 2019
Merged

Conversation

kares
Copy link
Member

@kares kares commented Aug 13, 2019

noticed a lot of unnecessary single element array wrapping at Enumerable's impls
... this could be aided with a simple override on the (native) BlockCallback

the most interesting piece is doing less work on Array#uniq (and also Enumerable#uniq)
also the Enumerable is still faster to have on the native end, numbers :

MRI 2.5.7

kares@clevo:~/workspace/oss/jruby$ ruby bench/core/array/unique_bench.rb
Rehearsal --------------------------------------------------------------------------------
Array#uniq (size: 8) [5000000x]                2.207314   0.000000   2.207314 (  2.207925)
Array#uniq (size: 32) [5000000x]               5.405314   0.000000   5.405314 (  5.406322)
Array#uniq(&block) (size: 8) [5000000x]        3.594613   0.000000   3.594613 (  3.595398)
Enumerable#uniq (size: 8) [5000000x]           4.275704   0.000000   4.275704 (  4.276550)
Enumerable#uniq (size: 32) [5000000x]          9.692536   0.000000   9.692536 (  9.693569)
Enumerable#uniq(&block) (size: 8) [5000000x]   5.502709   0.000000   5.502709 (  5.503421)
---------------------------------------------------------------------- total: 30.678190sec

                                                   user     system      total        real
Array#uniq (size: 8) [5000000x]                2.138970   0.000000   2.138970 (  2.139309)
Array#uniq (size: 32) [5000000x]               5.358952   0.000000   5.358952 (  5.359636)
Array#uniq(&block) (size: 8) [5000000x]        3.634595   0.000000   3.634595 (  3.635386)
Enumerable#uniq (size: 8) [5000000x]           4.194265   0.000000   4.194265 (  4.195012)
Enumerable#uniq (size: 32) [5000000x]          9.900353   0.000000   9.900353 (  9.902616)
Enumerable#uniq(&block) (size: 8) [5000000x]   5.433238   0.000000   5.433238 (  5.434582)

current JRuby (9.2.8.0)

Rehearsal --------------------------------------------------------------------------------
Array#uniq (size: 8) [5000000x]                1.980000   0.140000   2.120000 (  1.537581)
Array#uniq (size: 32) [5000000x]               4.430000   0.130000   4.560000 (  4.355980)
Array#uniq(&block) (size: 8) [5000000x]        3.390000   0.030000   3.420000 (  2.969637)
Enumerable#uniq (size: 8) [5000000x]           5.790000   0.020000   5.810000 (  5.115501)
Enumerable#uniq (size: 32) [5000000x]         15.500000   0.030000  15.530000 ( 15.426172)
Enumerable#uniq(&block) (size: 8) [5000000x]   7.700000   0.010000   7.710000 (  7.280119)
---------------------------------------------------------------------- total: 39.150000sec

                                                   user     system      total        real
Array#uniq (size: 8) [5000000x]                1.360000   0.000000   1.360000 (  1.331043)
Array#uniq (size: 32) [5000000x]               4.130000   0.000000   4.130000 (  4.100323)
Array#uniq(&block) (size: 8) [5000000x]        2.920000   0.010000   2.930000 (  2.867646)
Enumerable#uniq (size: 8) [5000000x]           5.080000   0.010000   5.090000 (  5.031277)
Enumerable#uniq (size: 32) [5000000x]         15.420000   0.040000  15.460000 ( 15.222436)
Enumerable#uniq(&block) (size: 8) [5000000x]   7.330000   0.030000   7.360000 (  7.235881)

this PR

Rehearsal --------------------------------------------------------------------------------
Array#uniq (size: 8) [5000000x]                1.940000   0.130000   2.070000 (  1.376955)
Array#uniq (size: 32) [5000000x]               3.470000   0.090000   3.560000 (  3.473800)
Array#uniq(&block) (size: 8) [5000000x]        2.950000   0.060000   3.010000 (  2.650662)
Enumerable#uniq (size: 8) [5000000x]           2.210000   0.020000   2.230000 (  1.840881)
Enumerable#uniq (size: 32) [5000000x]          5.040000   0.020000   5.060000 (  4.998871)
Enumerable#uniq(&block) (size: 8) [5000000x]   3.990000   0.010000   4.000000 (  3.533291)
---------------------------------------------------------------------- total: 19.930000sec

                                                   user     system      total        real
Array#uniq (size: 8) [5000000x]                1.160000   0.020000   1.180000 (  1.161547)
Array#uniq (size: 32) [5000000x]               3.330000   0.010000   3.340000 (  3.314024)
Array#uniq(&block) (size: 8) [5000000x]        2.600000   0.000000   2.600000 (  2.587071)
Enumerable#uniq (size: 8) [5000000x]           1.910000   0.000000   1.910000 (  1.844716)
Enumerable#uniq (size: 32) [5000000x]          5.090000   0.010000   5.100000 (  5.077093)
Enumerable#uniq(&block) (size: 8) [5000000x]   3.380000   0.000000   3.380000 (  3.301146)

kares added 6 commits Aug 13, 2019
re-using RubyHash internals (wout double hashing) seems nice
we do not need to fill a hash and than go on deleting entries
rely on Hash ordering + make Hash always map to ary's values
... confirming previous work made sense (at least for now):

```
----------------------------------------------------------------------
total: 30.678190sec

user     system
total        real
Array#uniq (size: 8) [5000000x]                2.138970   0.000000
2.138970 (  2.139309)
Array#uniq (size: 32) [5000000x]               5.358952   0.000000
5.358952 (  5.359636)
Array#uniq(&block) (size: 8) [5000000x]        3.634595   0.000000
3.634595 (  3.635386)
Enumerable#uniq (size: 8) [5000000x]           4.194265   0.000000
4.194265 (  4.195012)
Enumerable#uniq (size: 32) [5000000x]          9.900353   0.000000
9.900353 (  9.902616)
Enumerable#uniq(&block) (size: 8) [5000000x]   5.433238   0.000000
5.433238 (  5.434582)
```

```
----------------------------------------------------------------------
total: 39.150000sec

user     system
total        real
Array#uniq (size: 8) [5000000x]                1.360000   0.000000
1.360000 (  1.331043)
Array#uniq (size: 32) [5000000x]               4.130000   0.000000
4.130000 (  4.100323)
Array#uniq(&block) (size: 8) [5000000x]        2.920000   0.010000
2.930000 (  2.867646)
Enumerable#uniq (size: 8) [5000000x]           5.080000   0.010000
5.090000 (  5.031277)
Enumerable#uniq (size: 32) [5000000x]         15.420000   0.040000
15.460000 ( 15.222436)
Enumerable#uniq(&block) (size: 8) [5000000x]   7.330000   0.030000
7.360000 (  7.235881)
```

```
----------------------------------------------------------------------
total: 19.930000sec

user     system
total        real
Array#uniq (size: 8) [5000000x]                1.160000   0.020000
1.180000 (  1.161547)
Array#uniq (size: 32) [5000000x]               3.330000   0.010000
3.340000 (  3.314024)
Array#uniq(&block) (size: 8) [5000000x]        2.600000   0.000000
2.600000 (  2.587071)
Enumerable#uniq (size: 8) [5000000x]           1.910000   0.000000
1.910000 (  1.844716)
Enumerable#uniq (size: 32) [5000000x]          5.090000   0.010000
5.100000 (  5.077093)
Enumerable#uniq(&block) (size: 8) [5000000x]   3.380000   0.000000
3.380000 (  3.301146)
```
@kares kares added this to the JRuby 9.2.9.0 milestone Aug 13, 2019
@kares kares merged commit 9fb38a7 into jruby:master Aug 14, 2019
2 checks passed
@kares kares deleted the fast-uniq branch Oct 31, 2019
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

1 participant