Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b59ea63c7ed9
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: dc950b4acace
Choose a head ref
  • 4 commits
  • 5 files changed
  • 1 contributor

Commits on Jul 22, 2016

  1. [bench] for java.util.List-s ... using provided Ruby extensions

    ... a motivator for moving things into native (in 9.1.2) : 
    
    jruby 9.0.5.0 :
    ```
                     user     system      total        real
    ArrayList    8.170000   0.380000   8.550000 (  6.503745)
    LinkedList   6.320000   0.020000   6.340000 (  5.950724)
                     user     system      total        real
    ArrayList    5.670000   0.000000   5.670000 (  5.659923)
    LinkedList   5.870000   0.020000   5.890000 (  5.857407)
                     user     system      total        real
    ArrayList    5.650000   0.010000   5.660000 (  5.645130)
    LinkedList   5.870000   0.000000   5.870000 (  5.870076)
    ```
    
    current :
    ```
                     user     system      total        real
    ArrayList    2.760000   0.190000   2.950000 (  1.963845)
    LinkedList   2.340000   0.130000   2.470000 (  1.819008)
                     user     system      total        real
    ArrayList    1.920000   0.130000   2.050000 (  1.863589)
    LinkedList   1.540000   0.130000   1.670000 (  1.596286)
                     user     system      total        real
    ArrayList    1.760000   0.090000   1.850000 (  1.819901)
    LinkedList   1.540000   0.040000   1.580000 (  1.542850)
    ```
    kares committed Jul 22, 2016
    Copy the full SHA
    b37db2d View commit details
  2. Copy the full SHA
    d44ef29 View commit details
  3. [ji] override Enumerable#include? for java.util.Collection

    ... and use contains(Object) directly as the (Enumerable) base impl
    loops over the collection making it highly non-effective (e.g. for sets)
    
    9.0.5.0
    ```
                     user     system      total        real
    ArrayList#include? hit  11.670000   1.150000  12.820000 ( 11.749035)
    ArrayList#include? miss  9.840000   0.080000   9.920000 (  9.707464)
    ArrayList#contains hit   0.730000   0.010000   0.740000 (  0.370432)
    ArrayList#contains miss  0.350000   0.000000   0.350000 (  0.267981)
    HashSet#include? hit    13.720000   0.020000  13.740000 ( 13.593915)
    HashSet#include? miss    9.610000   0.020000   9.630000 (  9.543065)
    HashSet#contains hit     0.410000   0.000000   0.410000 (  0.256134)
    HashSet#contains miss    0.290000   0.000000   0.290000 (  0.213409)
    LHashSet#include? hit   11.560000   0.020000  11.580000 ( 11.453787)
    LHashSet#include? miss  11.840000   0.010000  11.850000 ( 11.752156)
    LHashSet#contains hit    0.320000   0.000000   0.320000 (  0.227460)
    LHashSet#contains miss   0.310000   0.000000   0.310000 (  0.220113)
    ```
    
    before
    ```
                     user     system      total        real
    ArrayList#include? hit   3.060000   0.000000   3.060000 (  3.057502)
    ArrayList#include? miss  3.220000   0.010000   3.230000 (  3.232130)
    ArrayList#contains hit   0.310000   0.000000   0.310000 (  0.308007)
    ArrayList#contains miss  0.320000   0.000000   0.320000 (  0.313187)
    HashSet#include? hit     3.040000   0.000000   3.040000 (  3.036603)
    HashSet#include? miss    3.240000   0.010000   3.250000 (  3.237065)
    HashSet#contains hit     0.160000   0.000000   0.160000 (  0.152719)
    HashSet#contains miss    0.150000   0.000000   0.150000 (  0.154513)
    LHashSet#include? hit    3.000000   0.000000   3.000000 (  2.987810)
    LHashSet#include? miss   3.160000   0.000000   3.160000 (  3.165118)
    LHashSet#contains hit    0.160000   0.000000   0.160000 (  0.160286)
    LHashSet#contains miss   0.230000   0.000000   0.230000 (  0.156899)
    ```
    
    after
    ```
                     user     system      total        real
    ArrayList#include? hit   0.110000   0.000000   0.110000 (  0.098661)
    ArrayList#include? miss  0.090000   0.000000   0.090000 (  0.087545)
    ArrayList#contains hit   0.350000   0.000000   0.350000 (  0.352668)
    ArrayList#contains miss  0.350000   0.000000   0.350000 (  0.351055)
    HashSet#include? hit     0.070000   0.000000   0.070000 (  0.061353)
    HashSet#include? miss    0.060000   0.000000   0.060000 (  0.058946)
    HashSet#contains hit     0.180000   0.000000   0.180000 (  0.172549)
    HashSet#contains miss    0.170000   0.000000   0.170000 (  0.171588)
    LHashSet#include? hit    0.090000   0.000000   0.090000 (  0.071044)
    LHashSet#include? miss   0.070000   0.000000   0.070000 (  0.060303)
    LHashSet#contains hit    0.300000   0.000000   0.300000 (  0.208889)
    LHashSet#contains miss   0.170000   0.000000   0.170000 (  0.166072)
    ```
    kares committed Jul 22, 2016
    1
    Copy the full SHA
    2e47a9d View commit details
  4. Copy the full SHA
    dc950b4 View commit details
73 changes: 73 additions & 0 deletions bench/java/bench_java_coll_member.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
require 'java'
require 'benchmark'

TIMES = (ARGV[0] || 5).to_i

CONTENTS = (1..36).to_a

TIMES.times do
Benchmark.bm(10) do |bm|
bm.report('ArrayList#include? hit ') do
list = java.util.ArrayList.new CONTENTS
hit = 32
1_000_000.times { list.include?(hit) }
end
bm.report('ArrayList#include? miss') do
list = java.util.ArrayList.new CONTENTS
miss = 0
1_000_000.times { list.include?(miss) }
end
bm.report('ArrayList#contains hit ') do
list = java.util.ArrayList.new CONTENTS
hit = 32
1_000_000.times { list.contains(hit) }
end
bm.report('ArrayList#contains miss') do
list = java.util.ArrayList.new CONTENTS
miss = 0
1_000_000.times { list.contains(miss) }
end

bm.report('HashSet#include? hit ') do
list = java.util.HashSet.new CONTENTS
hit = 32
1_000_000.times { list.include?(hit) }
end
bm.report('HashSet#include? miss ') do
list = java.util.HashSet.new CONTENTS
miss = 0
1_000_000.times { list.include?(miss) }
end
bm.report('HashSet#contains hit ') do
list = java.util.HashSet.new CONTENTS
hit = 32
1_000_000.times { list.contains(hit) }
end
bm.report('HashSet#contains miss ') do
list = java.util.HashSet.new CONTENTS
miss = 0
1_000_000.times { list.contains(miss) }
end

bm.report('LHashSet#include? hit ') do
list = java.util.LinkedHashSet.new CONTENTS
hit = 32
1_000_000.times { list.include?(hit) }
end
bm.report('LHashSet#include? miss ') do
list = java.util.LinkedHashSet.new CONTENTS
miss = 0
1_000_000.times { list.include?(miss) }
end
bm.report('LHashSet#contains hit ') do
list = java.util.LinkedHashSet.new CONTENTS
hit = 32
1_000_000.times { list.contains(hit) }
end
bm.report('LHashSet#contains miss ') do
list = java.util.LinkedHashSet.new CONTENTS
miss = 0
1_000_000.times { list.contains(miss) }
end
end
end
45 changes: 45 additions & 0 deletions bench/java/bench_java_list_ext.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'java'
require 'benchmark'

TIMES = (ARGV[0] || 5).to_i

TIMES.times do
Benchmark.bm(10) do |bm|
bm.report('ArrayList') do
list = java.util.ArrayList.new
one = 1.to_java
two = 2.to_java
thr = 3.to_java
1_000_000.times do
list.clear

list << one; list << two; list << thr

list[2] = one; list[0] = two; list[1] = thr

list.index(one)
list.rindex(thr)

list.to_a
end
end
bm.report('LinkedList') do
list = java.util.LinkedList.new
one = 1.to_java
two = 2.to_java
thr = 3.to_java
1_000_000.times do
list.clear

list << one; list << two; list << thr

list[2] = one; list[0] = two; list[1] = thr

list.index(one)
list.rindex(thr)

list.to_a
end
end
end
end
6 changes: 6 additions & 0 deletions core/src/main/java/org/jruby/javasupport/ext/JavaUtil.java
Original file line number Diff line number Diff line change
@@ -137,6 +137,12 @@ public static IRubyObject each_with_index(final ThreadContext context, final IRu
return JavaLang.Iterable.each_with_index(context, self, block);
}

@JRubyMethod(name = { "include?", "member?" })
public static RubyBoolean include_p(final ThreadContext context, final IRubyObject self, final IRubyObject obj) {
final java.util.Collection coll = unwrapJavaObject(self);
return context.runtime.newBoolean( coll.contains( obj.toJava(java.lang.Object.class) ) );
}

// NOTE: first might conflict with some Java types (e.g. java.util.Deque) thus providing a ruby_ alias
@JRubyMethod(name = { "first", "ruby_first" }) // re-def Enumerable#first
public static IRubyObject first(final ThreadContext context, final IRubyObject self) {
10 changes: 10 additions & 0 deletions core/src/main/ruby/jruby/java/java_ext/java.util.rb
Original file line number Diff line number Diff line change
@@ -19,6 +19,16 @@ def each_with_index(&block)
# stub implemented in org.jruby.javasupport.ext.JavaUtil.java
end

# Re-implemented for efficiency, so that we do not (`#each`) loop over the collection
# for types where its not necessary (e.g. *java.util.Set* instances), using (native) `contains`.
# @see Java::java::lang::Iterable#include?
# @return [true, false]
# @since 9.1.3
def include?(obj)
# stub implemented in org.jruby.javasupport.ext.JavaUtil.java
end
alias member? include?

# `Enumerable#first`
# @note Might collide with *java.util.Deque#getFirst* in which case you want to alias its ruby_ name
# so that the Ruby version is used e.g. `java.util.ArrayDeque.class_eval { alias first ruby_first }`
35 changes: 35 additions & 0 deletions spec/java_integration/extensions/collection_spec.rb
Original file line number Diff line number Diff line change
@@ -154,6 +154,41 @@
expect( set.to_a ).to eql ['0']
end

it '#include?' do
set = java.util.LinkedHashSet.new [1, 2, 3]
expect( set.include? 1 ).to be true
expect( set.member? 2 ).to be true
expect( set.contains 3 ).to be true
set.add 4; set.add 5.to_java
expect( set.include? 4 ).to be true
expect( set.include? 5 ).to be true
expect( set.contains 4 ).to be true
expect( set.contains 5 ).to be true
expect( set.contains 4.to_java ).to be true
expect( set.contains 5.to_java ).to be true
expect( set.contains 5.to_java(:byte) ).to be false
expect( set.contains 5.to_java(:short) ).to be false
expect( set.contains 6 ).to be false
expect( set.include? 6 ).to be false
expect( set.include? 4.to_java(:byte) ).to be false
expect( set.include? 4.to_java(:short) ).to be false
expect( set.include? 2.to_java ).to be true
expect( set.include? 2.to_java(:short) ).to be false
end

it '#include? (specific)' do
pending 'due Java numeric conversion can not add to_java(:xxx) to collection'

set = java.util.LinkedHashSet.new [2]
set << 1.to_java(:short)
expect( set.include? 1.to_java ).to be true
expect( set.include? 1.to_java(:short) ).to be true

set.add 3.to_java(:short)
expect( set.contains 3.to_java ).to be true
expect( set.contains 3.to_java(:short) ).to be true
end

it "should respect to_ary objects defined on iteration" do
class Pair
def initialize(a, b)