Skip to content

Instantly share code, notes, and snippets.

@alenia
Created July 22, 2011 02:19
Show Gist options
  • Save alenia/1098756 to your computer and use it in GitHub Desktop.
Save alenia/1098756 to your computer and use it in GitHub Desktop.
Why is this so much slower in Ruby than in Node?
def divisors_count(n)
count = 0
bound = Math.sqrt(n).floor
if bound*bound == n
count = 1
bound -= 1
elsif (bound+1)*(bound+1) == n
count = 1
end
(1..bound).each do |i|
count += 2 if n%i == 0
end
return count
end
exports.divisors_count = function (n) {
var count = 0
var bound = Math.floor(Math.sqrt(n))
if (bound*bound == n) {
count = 1;
bound -= 1;
}
else if ((bound+1)*(bound+1) == n) {
count = 1;
}
for(var i=1;i<=bound;i+=1) {
if (n%i ==0) {count += 2}
}
return count;
}
var methods = require('./eulerMethods.js');
var problem12 = function() {
var n=1;
var triangle = 0;
var divisors
while (true) {
triangle +=n;
divisors=methods.divisors_count(triangle);
if (divisors>=100) {
console.log(triangle, divisors);
}
if (divisors >= 500) {return triangle}
n += 1;
}
}
console.log(problem12());
require "./euler_methods"
def problem12
n=1
triangle = 0
while true
triangle +=n
divisors=divisors_count(triangle)
puts "#{triangle} #{divisors}" if divisors>=100
return triangle if divisors >= 500
n += 1
end
end
puts problem12.inspect
@alenia
Copy link
Author

alenia commented Jul 22, 2011

By my count it took approx. 0.7 seconds to run problem12.js in node.js v0.4.7. For problem12.rb, I ran it in ruby 1.9.2p180 and I only stuck with it for about 5-8 minutes or something, and it only got up to about 5m, when the correct solution is around 70m. I'm wondering what makes the .js file so much quicker to run.

**A few thoughts:
perhaps (1..bound) is significantly slower to implement than a for loop in js? I tried a while loop instead, didn't seem to help.
puts-ing a string might be much slower than console.logging, but it shouldn't be so much so to justify the difference.
Ruby's math engine might be terrible at Math.sqrt.

Comments appreciated.

@alenia
Copy link
Author

alenia commented Jul 22, 2011

quick test: varying speeds of math.sqrt is definitely not the problem.

JS:

$ cat sqrtTest.js
> console.log(Math.sqrt(987654321))
$ time node sqrtTest
> 31426.968052931865

real    0m0.048s
user    0m0.034s
sys 0m0.009s

Ruby:

$ cat sqrt_test.rb
> puts Math.sqrt(987654321)
$ time ruby sqrt_test.rb
> 31426.968052931865

real    0m0.014s
user    0m0.005s
sys 0m0.003s

@alenia
Copy link
Author

alenia commented Jul 22, 2011

More time tests:
Ruby:

$ cat sqrt_test.rb

i=0
while i<10000 do
  Math.sqrt(9876543210)
  i += 1
end

$ time ruby sqrt_test.rb 
real    0m0.018s
user    0m0.009s
sys     0m0.004s
$ vi sqrt_test.rb
$ cat sqrt_test.rb

i=0
while i<100000 do
  Math.sqrt(9876543210)
  i += 1
end

$ time ruby sqrt_test.rb 
real    0m0.043s
user    0m0.037s
sys     0m0.004s

JS:

$ cat sqrtTest.js

i=0;
while(i<10000) {
  Math.sqrt(9876543210);
  i += 1;
}

$ time node sqrtTest.js 
real    0m0.055s
user    0m0.040s
sys     0m0.008s
$ vi sqrtTest.js
$ cat sqrtTest.js

i=0;
while(i<100000) {
  Math.sqrt(9876543210);
  i += 1;
}
$ time node sqrtTest.js 
real    0m0.048s
user    0m0.039s
sys     0m0.008s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment