Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Ruby (http://www.velocityreviews.com/forums/f66-ruby.html)
-   -   1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds (http://www.velocityreviews.com/forums/t822512-1-ruby-result-101-seconds-2-java-result-9-8-seconds-3-perl-result-62-seconds.html)

 Michael Tan 06-21-2005 07:55 PM

1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds

--0-1157793495-1119383752=:96009
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?
1. Ruby result: 101 seconds
2. Java result:9.8 seconds
3. Perl result:62 seconds

Ruby:

def is_prime(number)
for i in 2..(number-1)
if number%i==0 then return false
end
end
return true
end
######### star here:How many primes in 2 to 50000?
max_number=50000
start_number=2
total=0
time=Time.now.to_i
for i in start_number..max_number
if is_prime(i)
#puts i
total+=1
end
end
time=Time.now.to_i-time
puts "There are #{total} primes between #{start_number} and #{max_number}"
puts "Time taken #{time} seconds"

Java :
import java.io.*;
class prime
{
private static boolean isPrime(long i)
{
for(long test = 2; test < i; test++)
{
if((i%test) == 0)
{
return false;
}
}
return true;
}
public static void main(String[] args) throws IOException
{
long start_time = System.currentTimeMillis();
long n_loops = 50000;
long n_primes = 0;
for(long i = 2; i <= n_loops; i++)
{
if(isPrime(i))
{
n_primes++;
}
}

long end_time = System.currentTimeMillis();
System.out.println(n_primes + " primes found");
System.out.println("Time taken = " + (end_time - start_time)+ "millseconds");
}
}

Perl:

######### star here:How many primes in 2 to 50000?

# start timer

\$start = time();

\$max_number=50000;

\$start_number=2;

\$total=0;

for (\$ii=\$start_number;\$ii<=\$max_number;\$ii++){

if (&is_prime(\$ii)==1)

{\$total+=1}

}

# end timer

\$end = time();

# report

print "There are ",\$total," primes between ",\$start_number," and ",\$max_number,"\n";

print "Time taken was ", (\$end - \$start), " seconds";

sub is_prime() {

my (\$number) = \$_[0];

my (\$si)=2;

for (\$si;\$si<\$number;\$si++){

if (\$number % \$si == 0) {

return 0;}

}

return 1

}

---------------------------------
Discover Yahoo!
Find restaurants, movies, travel & more fun for the weekend. Check it out!
--0-1157793495-1119383752=:96009--

 Ralph \PJPizza\ Siegler 06-21-2005 08:11 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds

On Wed, Jun 22, 2005 at 04:55:58AM +0900, Michael Tan wrote:
> Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?
> 1. Ruby result: 101 seconds
> 2. Java result:9.8 seconds
> 3. Perl result:62 seconds
>

Well, Ruby is a scripting language and not compiled, so its
results in the ballpark of Perl is about right. Only 10x
as slow as Java JVM? wow, that's pretty good, Ruby rocks!

Also, for more fun, run your Ruby through YARV and also
run zenoptimize on it

Benchmarks are great fun and prove nothing.

Ralph "PJPizza" Siegler

 David Mitchell 06-21-2005 08:32 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3.

Yeah, Ruby is always going to be slower than java, since java is
semi-compiled, whereas Ruby is interpreted from scratch. As for your
algorithm, it is sufficient to change your is_prime methods from:

for i in 2...number

to

for i in 2..Math.sqrt(number).to_i

Which will significantly reduce the number of tests you will perform.

David

Michael Tan wrote:
> Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?
> 1. Ruby result: 101 seconds
> 2. Java result:9.8 seconds
> 3. Perl result:62 seconds
>
>
> Ruby:
>
> def is_prime(number)
> for i in 2..(number-1)
> if number%i==0 then return false
> end
> end
> return true
> end
> ######### star here:How many primes in 2 to 50000?
> max_number=50000
> start_number=2
> total=0
> time=Time.now.to_i
> for i in start_number..max_number
> if is_prime(i)
> #puts i
> total+=1
> end
> end
> time=Time.now.to_i-time
> puts "There are #{total} primes between #{start_number} and #{max_number}"
> puts "Time taken #{time} seconds"
>
>
> Java :
> import java.io.*;
> class prime
> {
> private static boolean isPrime(long i)
> {
> for(long test = 2; test < i; test++)
> {
> if((i%test) == 0)
> {
> return false;
> }
> }
> return true;
> }
> public static void main(String[] args) throws IOException
> {
> long start_time = System.currentTimeMillis();
> long n_loops = 50000;
> long n_primes = 0;
> for(long i = 2; i <= n_loops; i++)
> {
> if(isPrime(i))
> {
> n_primes++;
> }
> }
>
> long end_time = System.currentTimeMillis();
> System.out.println(n_primes + " primes found");
> System.out.println("Time taken = " + (end_time - start_time)+ "millseconds");
> }
> }
>
>
> Perl:
>
> ######### star here:How many primes in 2 to 50000?
>
> # start timer
>
> \$start = time();
>
> \$max_number=50000;
>
> \$start_number=2;
>
> \$total=0;
>
> for (\$ii=\$start_number;\$ii<=\$max_number;\$ii++){
>
> if (&is_prime(\$ii)==1)
>
> {\$total+=1}
>
> }
>
> # end timer
>
> \$end = time();
>
> # report
>
> print "There are ",\$total," primes between ",\$start_number," and ",\$max_number,"\n";
>
> print "Time taken was ", (\$end - \$start), " seconds";
>
> sub is_prime() {
>
> my (\$number) = \$_[0];
>
> my (\$si)=2;
>
> for (\$si;\$si<\$number;\$si++){
>
> if (\$number % \$si == 0) {
>
> return 0;}
>
> }
>
> return 1
>
> }
>
>
>
>
> ---------------------------------
> Discover Yahoo!
> Find restaurants, movies, travel & more fun for the weekend. Check it out!

--
David Mitchell
Software Engineer
Telogis

 Florian Frank 06-21-2005 08:40 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3.

Michael Tan wrote:

>Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?
>
>

Your programs aren't the same. The Java and Perl program don't use
objects, the Ruby version does. Both the Perl and the Java version could
overflow, if numbers get too big, the Ruby program doesn't suffer from this.

And look, I just made the Ruby version, faster, smaller and more object
oriented:

class Integer
def prime?
not (2..Math.sqrt(self).floor).find { |i| self % i == 0 }
end
end
######### star here:How many primes in 2 to 50000?
start_number, max_number = 2, 50000
time = Time.now.to_f
total = (start_number..max_number).inject(0) { |s,i| s + (i.prime? ? 1 :
0) }
time = Time.now.to_f - time
puts "There are #{total} primes between #{start_number} and #{max_number}"
puts "Time taken %.3f seconds" % time

Now do the same in the other two languages...

--
Florian Frank

 Florian Frank 06-21-2005 08:45 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3.

Florian Frank wrote:
[...]

For correctness, perhaps even:

> class Integer
> def prime?

return false if self < 2

> not (2..Math.sqrt(self).floor).find { |i| self % i == 0 }
> end
> end

--
Florian Frank

 Jim Freeze 06-21-2005 09:00 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds

* Florian Frank <flori@nixe.ping.de> [2005-06-22 05:40:14 +0900]:

> def prime?
> not (2..Math.sqrt(self).floor).find { |i| self % i == 0 }
> end
> end

Have you tried skipping even numbers (excluding 2 of course)?
That should give you a little more speed.

--
Jim Freeze

 Florian Frank 06-21-2005 09:10 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3.

Jim Freeze wrote:

>Have you tried skipping even numbers (excluding 2 of course)?
>
>

Not me, but some guy did 2500 years ago.

>That should give you a little more speed.
>

It depends on how far you take your idea. It could get really slow on a
real computer, if you do it with big numbers.

--
Florian Frank

 Ara.T.Howard@noaa.gov 06-21-2005 09:26 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3.

On Wed, 22 Jun 2005, Michael Tan wrote:

> --0-1157793495-1119383752=:96009
> Content-Type: text/plain; charset=iso-8859-1
> Content-Transfer-Encoding: 8bit
>
> Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13... Are there setup issues? or it is normal?
> 1. Ruby result: 101 seconds
> 2. Java result:9.8 seconds
> 3. Perl result:62 seconds

if you just want a fast ruby version:

harp:~ > cat prime_inline.rb
def benchmark label, code
STDOUT.sync = true
puts "#{ '=' * 16 }\n#{ label }\n#{ '=' * 16 }"
fork do
GC.disable
a = Time::now.to_f
code.call
b = Time::now.to_f
puts " @ #{ b - a }"
end
Process::wait
end

prime_test = lambda{ (2 ... (2 ** 14)).each{|n| n.prime?} }

class Fixnum
def prime?
(2...self).each{|i| return false if self % i == 0}
return true
end
end
benchmark 'pure ruby', prime_test

require 'inline'
class Fixnum
inline do |builder|
builder.c_raw <<-src
static VALUE
is_prime_c (int argc, VALUE *argv, VALUE self) {
long i, n = FIX2LONG (self);
for (i = 2; i < n; i++) if (n % i == 0) return Qfalse;
return Qtrue;
}
src
end
alias prime? is_prime_c
end
benchmark 'inline c', prime_test

harp:~ > ruby prime_inline.rb
================
pure ruby
================
@ 14.9205560684204
================
inline c
================
@ 0.539831876754761

so that's about two orders of magnitude speed-up for less than 10 extra lines
of code - and you still get nice things like overflow safety.

hth.

-a
--
================================================== =============================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| My religion is very simple. My religion is kindness.
| --Tenzin Gyatso
================================================== =============================

 Ken Kunz 06-21-2005 10:16 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds

Here's a version that skips even numbers:

class Integer
def is_prime?
return false if self < 2
return false if self % 2 == 0
max_factor = Math.sqrt(self).to_i
3.step(max_factor, 2) {|i| return false if self % i == 0 }
return true
end
end

And here's a benchmark comparison:

require 'benchmark'

Benchmark.bm(12) do |x|
x.report("original:") { 2.upto(50000) {|i| is_prime(i) } }
x.report("Florian's:") { 2.upto(50000) {|i| i.prime? } }
x.report("Ken's:") { 2.upto(50000) {|i| i.is_prime? } }
end

user system total real
original: 171.767000 0.020000 171.787000 (174.627000)
Florian's: 2.804000 0.010000 2.814000 ( 2.814000)
Ken's: 1.041000 0.000000 1.041000 ( 1.042000)

What's more important, how fast a program _runs_, or how fast I can
_write_ it? With Ruby, I can almost always write something that is
"fast enough", and I can write it a whole lot quicker than in Java or
C. The above (semi-) optimized version only took 2 minutes to write.
(And as a side note... it was more fun to write it in Ruby :) )

And when you need some extra umph... there's always YARV or ruby2c...
and when you really need it (rarely), manually optimized C.

Cheers,
Ken

 Isaac Gouy 06-21-2005 11:18 PM

Re: 1. Ruby result: 101 seconds , 2. Java result:9.8 seconds, 3. Perl result:62 seconds

Michael Tan wrote:
> Just new to Ruby since last week, running my same functional program on the windows XP(Pentium M1.5G), the Ruby version is 10 times slower than the Java version. The program is to find the prime numbers like 2, 3,5, 7, 11, 13...

Refer to the simple programs on The Great Computer Language Shootout -
then you can blame those guys for doing meaningless benchmarking rather
than taking the heat yourself :-)

http://shootout.alioth.debian.org/gr...a&sort=fullcpu

All times are GMT. The time now is 01:10 AM.