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

float equality problem #5243

Closed
ahorek opened this issue Jul 8, 2018 · 4 comments
Closed

float equality problem #5243

ahorek opened this issue Jul 8, 2018 · 4 comments
Milestone

Comments

@ahorek
Copy link
Contributor

ahorek commented Jul 8, 2018

Environment

jruby 9.2.1.0-SNAPSHOT (2.5.0) 2018-07-07 9d52bae Java HotSpot(TM) 64-Bit Server VM 9.0.4+11 on 9.0.4+11 +jit [linux-x86_64]

it's not a regression, it behaves the same way on 9.1.15.0

Expected Behavior

1.0.equal?(1.0) => true

mri
1.0.object_id
=> -36028797018963966
1.0.object_id
=> -36028797018963966 (weird number, but same id)
1.1.object_id
=> -32425917317067566

truffle ruby
1.0.object_id
=> 41500670566219120640
1.0.object_id
=> 41500670566219120640 (same id)
1.1.object_id
=> 41501120926181857690

1.object_id
=> 3
1.object_id
=> 3

Actual Behavior

1.0.equal?(1.0) => false

jruby
1.0.object_id
=> 4642
1.0.object_id
=> 4644 (object_id is always incremented by two)
1.1.object_id
=> 4646

integers don't increment object_id
1.object_id
=> 3
1.object_id
=> 3
1.equal?(1)
=> true
rspec test
       expect(10.0).to be(10.0)

       expected #<Float:4648> => 10.0
             got #<Float:4650> => 10.0

it's probably because of this issue isn't implemented in jruby? https://bugs.ruby-lang.org/issues/6763

@ahorek
Copy link
Contributor Author

ahorek commented Jul 8, 2018

ok, it's just a side-effect of an optimalization that MRI uses since ruby 2.0 https://bugs.ruby-lang.org/issues/6763

jruby just works like ruby 1.9.x

do you think it's worth to implement it in jruby?

i= 0; f = 0.0
while i<30_000_000
  i+= 1
  f += 0.1; f -= 0.1
  f += 0.1; f -= 0.1
  f += 0.1; f -= 0.1
end

jruby-head
3.027M (±10.9%)
jruby-head + invoke dynamic
3.229M (±11.1%)
ruby 1.9.3
2.698M (± 2.6%) i/s
ruby 2.5.1
5.042M (± 4.4%) i/s

@headius
Copy link
Member

headius commented Jul 12, 2018

We will not (can not) implement this because there's no way to mix pointers (references) and primitive types on the JVM. The fact that Fixnum-ranged Integers and Floats are now immediate values (tagged pointers) on CRuby is an implementation side-effect you should not rely on.

@headius headius closed this as completed Jul 12, 2018
@headius
Copy link
Member

headius commented Jul 12, 2018

Also, I'm not sure what benchmark you were running, but I looped ten times over your example, recording the time to complete each 30M loop, and my numbers don't look anything like yours:

[] ~/projects/jruby $ jruby -Xcompile.invokedynamic -Xfixnum.cache=false blah.rb
0.770524
0.5920409999999999
0.436415
0.650771
0.35050499999999996
0.309486
0.308033
0.309523
0.309396
0.308825

[] ~/projects/jruby $ (pickjdk 1 ; jruby -Xcompile.invokedynamic -Xfixnum.cache=false blah.rb)
New JDK: graalvm
0.841652
0.413373
0.215291
0.215343
0.214958
0.2148
0.214555
0.216206
0.214374
0.214025

[] ~/projects/jruby $ rvm ruby-2.5 do ruby blah.rb
2.871346
2.820174
2.806823
2.809709
2.814032
2.808486
2.800355
2.811274
2.800535
2.828576

JRuby should definitely be faster than MRI even without flonums.

@headius headius added this to the Won't Fix milestone Jul 12, 2018
@ahorek
Copy link
Contributor Author

ahorek commented Jul 12, 2018

I retested and it's indeed faster on jruby, thanks @headius

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

No branches or pull requests

2 participants