Ruby performance

The problem is that with every iteration inside #times, Ruby yield the
current "index" to the block - even if the block doesn't use this
variable at all.

And calling the block is no small operation... start here[1] (this is
the #times method, as defined in C) and see how deep the rabbit hole
goes.

[1] http://rxr.whitequark.org/mri/source/numeric.c#3441

-- Matma Rex

···

2012/7/2 Dan Connelly <lists@ruby-forum.com>:

Here's my contribution:

Ruby:
i = 0
10_000_000.times { i += 1 }
puts i

Perl:
for my $n ( 0 .. 1e7 - 1) {
  $i ++
}
print "$i\n"

Result:
Ruby: 2.970 seconds
Perl: 0.682 seconds

Wow...

I should provide version numbers... the RHEL on work machines is pretty
backwards.

Ruby: 1.8.1
Perl: 5.8.8

I ran on my personal Macbook Air with Ruby 1.9.3 and Perl 5.10, and Perl
was only 2x faster. So it seems Ruby 1.9 is indeed substantially faster
(assuming Perl is fairly stable).

Curious when I did the loop in C how huge the speed increase was with
-O1 versus -O0...

#include <stdio.h>
int main(void) {
  int i = 0;
  while (++i < 10000000);
  printf("i = %d", i);
  return 0;
}

but that's a bit off-topic...

···

--
Posted via http://www.ruby-forum.com/.

Dan Connelly писал 03.07.2012 04:06:

I should provide version numbers... the RHEL on work machines is pretty
backwards.

Ruby: 1.8.1
Perl: 5.8.8

1.8.1?!! That's just ancient. I doubt it's compatible with any recent gems.
It seems that you need at least 1.8.6 even for the most compatible of them.

I ran on my personal Macbook Air with Ruby 1.9.3 and Perl 5.10, and Perl
was only 2x faster. So it seems Ruby 1.9 is indeed substantially faster
(assuming Perl is fairly stable).

Curious when I did the loop in C how huge the speed increase was with
-O1 versus -O0...

#include <stdio.h>
int main(void) {
  int i = 0;
  while (++i < 10000000);
  printf("i = %d", i);
  return 0;
}

but that's a bit off-topic...

I don't know your precise GCC version so I won't comment on any particular
optimization details my GCC version does, but I'd advise you to read the
relevant assembly. The change could be anything from binding `i' to
a register to pre-computing the entire loop (yeah, recent GCC can do that.)

···

--
   WBR, Peter Zotov.

cmon, with objects, speed becomes relative...
those who wants just speed can leave ruby...

$ for x in "ruby ruby1.rb" "ruby ruby2.rb" "perl perl1.pl"; do echo
$x; time $x;echo ; done

ruby ruby1.rb
10000000

real 0m0.875s
user 0m0.930s
sys 0m0.040s

ruby ruby2.rb
10000001

real 0m0.312s
user 0m0.340s
sys 0m0.020s

perl perl1.pl

real 0m0.518s
user 0m0.520s
sys 0m0.000s

botp@u:~
$ for x in "ruby1.rb" "ruby2.rb" "perl1.pl"; do echo \#$x; cat $x;echo ; done

#ruby1.rb
i = 0
10_000_000.times { i += 1 }
puts i

#ruby2.rb
i=0
while i <= 10_000_000
  i += 1
end

puts i

#perl1.pl
#Perl:
for my $n ( 0 .. 1e7 - 1) {
   $i ++
}

···

On Tue, Jul 3, 2012 at 8:06 AM, Dan Connelly <lists@ruby-forum.com> wrote:

I ran on my personal Macbook Air with Ruby 1.9.3 and Perl 5.10, and Perl
was only 2x faster.

Dan Connelly wrote in post #1067093:

Curious when I did the loop in C how huge the speed increase was with
-O1 versus -O0...

No surprise there; the loop doesn't do anything, so the optimizer can
reduce the program to "return 0". And that's what is wrong with a
benchmark like this. Rule of thumb, if you have to disable the optimizer
to get a result, your benchmark is useless.

···

--
Posted via http://www.ruby-forum.com/\.

botp wrote in post #1067101:

#ruby2.rb
i=0
while i <= 10_000_000
  i += 1
end

puts i

#perl1.pl
#Perl:
for my $n ( 0 .. 1e7 - 1) {
   $i ++
}

This is a slight cheat, since my examples had addition independent of
loop control. But nevertheless if I do the following:

i, j = 0,0
while j < 10_000_000
  i+=1
  j+=1
end
puts "i = #{i}"

Then the Perl and Ruby are very close in speed (versions 5.10, 1.9),
which was non-obvious to me, since on the face of it,

10_000_000.times { i += 1 }

seems cleaner (seems the details are in how the block is invoked in each
case).

It makes me wonder if there's room for a more efficient looping
construct, since a while-loop is clumsy. But perhaps performance is an
insufficient reason to justify language changes.

···

--
Posted via http://www.ruby-forum.com/\.

Note that the overhead for starting up and exiting the interpreter has an impact on your results when you benchmark like that.

  $ time for i in {0..100}; do ruby -e ''; done

  real 0m2.395s
  user 0m1.600s
  sys 0m0.628s

  $ time for i in {0..100}; do perl -e ''; done

  real 0m0.526s
  user 0m0.176s
  sys 0m0.300s

(Ruby 1.9.3, Perl 5.14.2.)

···

On 07/03/2012 03:34 AM, botp wrote:

$ for x in "ruby ruby1.rb" "ruby ruby2.rb" "perl perl1.pl"; do echo
$x; time $x;echo ; done

--
Lars Haugseth

Oh my god... are you guys still mentarbating over this crap?

First off... compare apples to apples. ruby 1.9 loads rubygems by default.

4605 % time for i in {0..100}; do ruby19 -e ''; done

real 0m3.089s
user 0m2.066s
sys 0m0.663s

4606 % time for i in {0..100}; do ruby19 --disable-gems -e ''; done

real 0m1.414s
user 0m0.771s
sys 0m0.438s

Second. Be glad you're not running python or anything on the jvm (compare `time gem list` vs `time jgem list`):

4604 % time for i in {0..100}; do python -c ''; done

real 0m14.186s
user 0m11.212s
sys 0m1.717s

Third... WHO CARES?!?!? This is all bullshit comparisons for bullshit reasons. You don't use ruby for speed of runtime. You use it because you'll be done AND have profiled and optimized the bottlenecks before they're done. You use it because it's a great language to develop in. You use it to GET STUFF DONE and AVOID THESE THREADS.

···

On Jul 3, 2012, at 01:47 , Lars Haugseth wrote:

On 07/03/2012 03:34 AM, botp wrote:

$ for x in "ruby ruby1.rb" "ruby ruby2.rb" "perl perl1.pl"; do echo
$x; time $x;echo ; done

Note that the overhead for starting up and exiting the interpreter has an impact on your results when you benchmark like that.

$ time for i in {0..100}; do ruby -e ''; done

real 0m2.395s
user 0m1.600s
sys 0m0.628s

$ time for i in {0..100}; do perl -e ''; done

real 0m0.526s
user 0m0.176s
sys 0m0.300s

(Ruby 1.9.3, Perl 5.14.2.)

Why does j even exist in this?

    i = 0
    while j < 10_000_000
      i += 1
    end
    puts "i = #{i}"

Is the j there in some attempt to simulate a case where the loop
increment variable is not redundant with the operations taking place
within the loop?

···

On Tue, Jul 03, 2012 at 12:19:52PM +0900, Dan Connelly wrote:

botp wrote in post #1067101:

This is a slight cheat, since my examples had addition independent of
loop control. But nevertheless if I do the following:

i, j = 0,0
while j < 10_000_000
  i+=1
  j+=1
end
puts "i = #{i}"

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Ryan Davis wrote in post #1067161:

Third... WHO CARES?!?!? This is all bullshit comparisons for bullshit
reasons. You don't use ruby for speed of runtime. You use it because
you'll be done AND have profiled and optimized the bottlenecks before
they're done. You use it because it's a great language to develop in.
You use it to GET STUFF DONE and AVOID THESE THREADS.

I agree, and I think the whole benchmarking has nothing to do with the
original topic.

The OP was talking about "huge arrays", so I rather think *this* is the
bottleneck. Using a specialized language for data processing (maybe SQL)
will probably make much more sense than trying to make Ruby some
milliseconds faster.

I'm no expert, but processing "huge arrays" in Ruby or even Java just
sounds wrong to me.

···

--
Posted via http://www.ruby-forum.com/\.

Chad Perrin wrote in post #1067210:

Is the j there in some attempt to simulate a case where the loop
increment variable is not redundant with the operations taking place
within the loop?

Yes -- I wanted to "do something" in the loop, so I incremented a
counter. I admit it's a crappy benchmark; I wanted something simple but
not completely trivial.

···

--
Posted via http://www.ruby-forum.com/\.

Jan E. wrote in post #1067169:

Ryan Davis wrote in post #1067161:

Third... WHO CARES?!?!? This is all bullshit comparisons for bullshit
reasons.

This sounds like a religious discussion.

I write code which does non-trivial calculations I'd prefer to run
faster. I also want it to be easier to run and maintain. If there was
really a factor of two difference between Ruby and Perl, that would be
an issue: it would bias me towards Perl. And if one type of loop were
really much faster than another, I'd tend to want to use that loop.

It's not speed over everything else. But speed is a good thing to know
about. Engineering decisions are all about trade-offs.

···

--
Posted via http://www.ruby-forum.com/\.

If you pretend that this thread is full of scientific study or engineering decisions, then it is you who are involved in the religious discussion. The code/numbers being bandied about here are neither rigorous, nor informative, nor pertinent to the OP's actual needs.

···

On Jul 3, 2012, at 05:41 , Dan Connelly wrote:

Jan E. wrote in post #1067169:

Ryan Davis wrote in post #1067161:

Third... WHO CARES?!?!? This is all bullshit comparisons for bullshit
reasons.

This sounds like a religious discussion.

I write code which does non-trivial calculations I'd prefer to run
faster. I also want it to be easier to run and maintain. If there was
really a factor of two difference between Ruby and Perl, that would be
an issue: it would bias me towards Perl. And if one type of loop were
really much faster than another, I'd tend to want to use that loop.

It's not speed over everything else. But speed is a good thing to know
about. Engineering decisions are all about trade-offs.