-
-
Save funny-falcon/2020108 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby | |
require 'yaml' | |
y=[] | |
(1..10000).each{|x| | |
#next unless x/2==(1.0*x)/2 | |
z=x | |
divisors=[1] | |
_continue=true | |
while _continue | |
_continue=false | |
((divisors.last+1)..z).each{|w| | |
r=z/w | |
if (1.0*z)/w==r && w<x | |
divisors<<w | |
_continue=true | |
break | |
end | |
} | |
end | |
if divisors.inject(&:+)>x and (3..(divisors.count)).find{|w| divisors.combination(w).find{|w2| w2.inject(&:+)==x } } | |
y<<x | |
end | |
} | |
puts "amount: #{y.count}" |
#!/usr/bin/env ruby | |
require 'yaml' | |
class Test | |
attr_reader :y | |
def initialize(up) | |
@up = up | |
@y = [] | |
end | |
def perform | |
for x in 1..@up | |
divisors, w = [1], 1 | |
while (w = get_next(w+1, x)) | |
divisors << w | |
end | |
y << x if sum(divisors) > x && check(divisors, x) | |
end | |
self | |
end | |
def get_next(from, z) | |
w = from | |
while w < z | |
return w if z/w == (1.0*z)/w | |
w += 1 | |
end | |
nil | |
end | |
def sum(ar) | |
s = ar[0] | |
i, up = 1, ar.size | |
while i < up | |
s += ar[i] | |
i += 1 | |
end | |
s | |
end | |
def check(divisors, x) | |
(3..(divisors.count)).find{|w| | |
divisors.combination(w).find{|w2| | |
sum(w2) == x | |
} | |
} | |
end | |
end | |
puts "amount: #{Test.new(10000).perform.y.count}" |
and here is rbx:
$ rvm rbx-head-d19 do time ruby -v ugly_test.rb
rubinius 2.0.0dev (1.9.3 9a4b4c1c yyyy-mm-dd JI) [x86_64-unknown-linux-gnu]
amount: 2481
1789.27user 1.19system 30:07.73elapsed 99%CPU (0avgtext+0avgdata 185024maxresident)k
36288inputs+0outputs (107major+13196minor)pagefaults 0swaps
As I remember last time it was around 43 minutes so also slight speedup.
update for latest rbx:
$ time rvm rbx do ruby -v ugly_test.rb
rubinius 2.0.0dev (1.9.3 b4aa36e4 yyyy-mm-dd JI) [x86_64-unknown-linux-gnu]
amount: 2481
real 3m37.907s
user 3m33.326s
sys 0m0.516s
big speedup, still slower but already a lot better then before, here is 1.9.3-p125 for comparison
$ time rvm 1.9.3 do ruby -v ugly_test.rb
ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
amount: 2481
real 2m35.360s
user 2m32.542s
sys 0m0.378s
and jruby-head on java7 is over 2 times faster:
$ time rvm jruby-head do ruby -v ugly_test.rb
jruby 1.7.0.dev (ruby-1.9.3-p139) (2012-04-02 f031f63) (Java HotSpot(TM) 64-Bit Server VM 1.7.0_03) [linux-amd64-java]
amount: 2481
real 1m29.288s
user 1m25.240s
sys 0m1.670s
It is big step forward for rbx!!!
I'm more interested in IO behavior though. Maybe it improved too.
My numbers seem to put JRuby farther ahead of Ruby 1.9.3 than your numbers:
Ruby 1.9.3:
111.640000 0.080000 111.720000 (111.722357)
JRuby master on Java 7u4:
41.103000 0.000000 41.103000 ( 41.104000)
JRuby's run time is 36% of Ruby 1.9.3's, compared to around 58% in your case. Nearly 3x faster rather than less than 2x. Perhaps JRuby has improved since this run? Perhaps my dual cores are helping (the JVM does use multiple cores for GC)?
A small change improves JRuby further... replace the #[] calls in sum with #at calls:
real 0m33.895s
user 0m37.502s
sys 0m0.421s
In JRuby, #[] is flagged as a method that requires a heap-based scope because some versions of it set $~ (backref). Using .at avoids that.
We plan to fix that deoptimization, but it does make a difference right now.
that could be also java version (mine is a bit older):
$ java -version
java version "1.7.0_03"
Java(TM) SE Runtime Environment (build 1.7.0_03-b04)
Java HotSpot(TM) 64-Bit Server VM (build 22.1-b02, mixed mode)
In JRuby, #[] is flagged as a method that requires a heap-based scope because some versions of it set $~ (backref). Using .at avoids that.
Wow :)
@mpapis that certainly could be true. There's also been some optimization work on JRuby master that may not be in your copy.
Non-block loops are faster in JRuby (and maybe in others) because blocks have a lot of hidden overhead. Specifically, the closure state (local vars, etc), argument processing, and in JRuby some deoptimizations happen because blocks can potentially be used as bindings (grr). Future JRuby (probably post 1.7) will do a better job optimizing and inlining blocks, but it's much harder than just inlining (or letting the JVM inline) method bodies and simple loops.