[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

[shootout] n body problem

Martin DeMello

3/12/2005 5:29:00 PM

Here's a first pass at the n body problem in the shootout - I've tried
to strike a balance between idiomatic and fast, the main optimisation
being to remove all object creation from the advance() loop as far as
possible, in favour of methods that updated an existing object.

http://shootout.alioth.debian.org/benchmark.php?test=nbody&lang=all&so...

-----------------------------------------------------------------------

include Math

SOLAR_MASS = 4*PI*PI
DAYS_PER_YEAR = 365.24

Vector3D = Struct.new("Vector3D", :x, :y, :z)

class Vector3D

def *(val)
Vector3D.new(*self.map {|i| i * val})
end

def /(val)
Vector3D.new(*self.map {|i| i / val})
end

#in-place add with scale
# a.adds(b, s) -> a += b*s

def adds(other, scale)
3.times {|i| self[i] += other[i] * scale}
end

def subs(other, scale)
adds(other, -scale)
end

def magnitude
d = self.inject(0) {|a,v| a + v*v}
sqrt(d)
end

# |self - other|
def dmag(other)
sqrt((0...3).inject(0) {|a, i| d = (self[i] - other[i]); a + d * d})
end
end

class Planet
attr_accessor :pos, :v, :mass

def initialize(x, y, z, vx, vy, vz, mass)
@pos = Vector3D.new(x, y, z)
@v = Vector3D.new(vx, vy, vz) * DAYS_PER_YEAR
@mass = mass * SOLAR_MASS
end

def distance(other)
self.pos.dmag(other.pos)
end
end

jupiter = Planet.new(
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03,
7.69901118419740425e-03,
-6.90460016972063023e-05,
9.54791938424326609e-04)

saturn = Planet.new(
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03,
4.99852801234917238e-03,
2.30417297573763929e-05,
2.85885980666130812e-04)

uranus = Planet.new(
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03,
2.37847173959480950e-03,
-2.96589568540237556e-05,
4.36624404335156298e-05)

neptune = Planet.new(
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03,
1.62824170038242295e-03,
-9.51592254519715870e-05,
5.15138902046611451e-05)

sun = Planet.new(0, 0, 0, 0, 0, 0, 1)

class Array
def each_pair
a = []
each_index {|i|
((i+1)...length).each {|j|
yield at(i), at(j)
}
}
end
end

bodies = [sun, jupiter, saturn, uranus, neptune]

class << bodies
def advance(dt)
mag = m1 = m2 = nil
each_pair {|b1, b2|
d = b1.distance(b2)
mag = dt/(d*d*d)

m1 = b1.mass * mag
m2 = b2.mass * mag

b1.v.adds(b2.pos, m2)
b1.v.subs(b1.pos, m2)
b2.v.adds(b1.pos, m1)
b2.v.subs(b2.pos, m1)
}

each {|b| b.pos.adds(b.v, dt)}
end

def energy
e = 0
each {|b| e += 0.5 * b.mass * (b.v.magnitude ** 2) }
each_pair {|b1, b2| e -= (b1.mass * b2.mass) / b1.distance(b2) }
e
end

def offset_momentum
p = Vector3D.new(0,0,0)
sun = self[0]
each {|b| p.adds(b.v, b.mass) }
sun.v.subs(p, 1.0/sun.mass)
end
end

require 'benchmark'

Benchmark.bm {|x|
x.report {
bodies.offset_momentum
puts bodies.energy
Integer(ARGV[0]).times { bodies.advance(0.01) }
puts bodies.energy
}
}



22 Answers

Isaac Gouy

3/12/2005 5:39:00 PM

0


Martin DeMello wrote:
> Here's a first pass at the n body problem in the shootout - I've
tried
> to strike a balance between idiomatic and fast, the main optimisation
> being to remove all object creation from the advance() loop as far as
> possible, in favour of methods that updated an existing object.
>
>
http://shootout.alioth.debian.org/benchmark.php?test=nbody&lang=all&so...
>
>
-----------------------------------------------------------------------
>
> include Math
>
> SOLAR_MASS = 4*PI*PI
> DAYS_PER_YEAR = 365.24
>
> Vector3D = Struct.new("Vector3D", :x, :y, :z)
>
> class Vector3D
>
> def *(val)
> Vector3D.new(*self.map {|i| i * val})
> end
>
> def /(val)
> Vector3D.new(*self.map {|i| i / val})
> end
>
> #in-place add with scale
> # a.adds(b, s) -> a += b*s
>
> def adds(other, scale)
> 3.times {|i| self[i] += other[i] * scale}
> end
>
> def subs(other, scale)
> adds(other, -scale)
> end
>
> def magnitude
> d = self.inject(0) {|a,v| a + v*v}
> sqrt(d)
> end
>
> # |self - other|
> def dmag(other)
> sqrt((0...3).inject(0) {|a, i| d = (self[i] - other[i]); a + d *
d})
> end
> end
>
> class Planet
> attr_accessor :pos, :v, :mass
>
> def initialize(x, y, z, vx, vy, vz, mass)
> @pos = Vector3D.new(x, y, z)
> @v = Vector3D.new(vx, vy, vz) * DAYS_PER_YEAR
> @mass = mass * SOLAR_MASS
> end
>
> def distance(other)
> self.pos.dmag(other.pos)
> end
> end
>
> jupiter = Planet.new(
> 4.84143144246472090e+00,
> -1.16032004402742839e+00,
> -1.03622044471123109e-01,
> 1.66007664274403694e-03,
> 7.69901118419740425e-03,
> -6.90460016972063023e-05,
> 9.54791938424326609e-04)
>
> saturn = Planet.new(
> 8.34336671824457987e+00,
> 4.12479856412430479e+00,
> -4.03523417114321381e-01,
> -2.76742510726862411e-03,
> 4.99852801234917238e-03,
> 2.30417297573763929e-05,
> 2.85885980666130812e-04)
>
> uranus = Planet.new(
> 1.28943695621391310e+01,
> -1.51111514016986312e+01,
> -2.23307578892655734e-01,
> 2.96460137564761618e-03,
> 2.37847173959480950e-03,
> -2.96589568540237556e-05,
> 4.36624404335156298e-05)
>
> neptune = Planet.new(
> 1.53796971148509165e+01,
> -2.59193146099879641e+01,
> 1.79258772950371181e-01,
> 2.68067772490389322e-03,
> 1.62824170038242295e-03,
> -9.51592254519715870e-05,
> 5.15138902046611451e-05)
>
> sun = Planet.new(0, 0, 0, 0, 0, 0, 1)
>
> class Array
> def each_pair
> a = []
> each_index {|i|
> ((i+1)...length).each {|j|
> yield at(i), at(j)
> }
> }
> end
> end
>
> bodies = [sun, jupiter, saturn, uranus, neptune]
>
> class << bodies
> def advance(dt)
> mag = m1 = m2 = nil
> each_pair {|b1, b2|
> d = b1.distance(b2)
> mag = dt/(d*d*d)
>
> m1 = b1.mass * mag
> m2 = b2.mass * mag
>
> b1.v.adds(b2.pos, m2)
> b1.v.subs(b1.pos, m2)
> b2.v.adds(b1.pos, m1)
> b2.v.subs(b2.pos, m1)
> }
>
> each {|b| b.pos.adds(b.v, dt)}
> end
>
> def energy
> e = 0
> each {|b| e += 0.5 * b.mass * (b.v.magnitude ** 2) }
> each_pair {|b1, b2| e -= (b1.mass * b2.mass) / b1.distance(b2) }
> e
> end
>
> def offset_momentum
> p = Vector3D.new(0,0,0)
> sun = self[0]
> each {|b| p.adds(b.v, b.mass) }
> sun.v.subs(p, 1.0/sun.mass)
> end
> end
>
> require 'benchmark'
>
> Benchmark.bm {|x|
> x.report {
> bodies.offset_momentum
> puts bodies.energy
> Integer(ARGV[0]).times { bodies.advance(0.01) }
> puts bodies.energy
> }
> }

Excellent!

Before we can use it I'm afraid you have to contribute it to the
shootout, we can't just skim programs from other places.

Please send programs to the mailing list or send them using the message
form or email them to igouy2

http://shootout.alioth.debian.org/faq.php?so...

best wishes, Isaac

Martin DeMello

3/12/2005 5:49:00 PM

0

igouy@yahoo.com wrote:

> Before we can use it I'm afraid you have to contribute it to the
> shootout, we can't just skim programs from other places.

Will do, once the list has had time to improve it. This is just a first
stab at the problem.

martin

gabriele renzi

3/13/2005 1:39:00 AM

0

igouy@yahoo.com ha scritto:

>
>
> Excellent!
>
> Before we can use it I'm afraid you have to contribute it to the
> shootout, we can't just skim programs from other places.
>
> Please send programs to the mailing list or send them using the message
> form or email them to igouy2
>
> http://shootout.alioth.debian.org/faq.php?so...
>
> best wishes, Isaac
>

is the input from the form actually received?
I think I sent one or two comments/impèlementations in the past (such as
takfp, which is a trivial one) but I had the impression they where not
considered (I thhought contribution out of the ml were not considered)

Isaac Gouy

3/13/2005 6:20:00 AM

0


gabriele renzi wrote:
> igouy@yahoo.com ha scritto:
>
> >
> >
> > Excellent!
> >
> > Before we can use it I'm afraid you have to contribute it to the
> > shootout, we can't just skim programs from other places.
> >
> > Please send programs to the mailing list or send them using the
message
> > form or email them to igouy2
> >
> > http://shootout.alioth.debian.org/faq.php?so...
> >
> > best wishes, Isaac
> >
>
> is the input from the form actually received?

Hmmm I'll do a test and see if we receive what we should.


> I think I sent one or two comments/impèlementations in the past
(such as
> takfp, which is a trivial one) but I had the impression they where
not
> considered (I thhought contribution out of the ml were not
considered)

Sending code explicitly as a contribution to the shootout mailing list
or to our email seems fine - just say that you are giving it for
publication (shootout uses a revised BSD license).

We do sometimes lose stuff and generally make mistakes, and we do
really want contributions from knowledgeable language users.

Isaac Gouy

3/13/2005 5:08:00 PM

0


igouy@yahoo.com wrote:
> gabriele renzi wrote:
> > igouy@yahoo.com ha scritto:
> >
> > >
> > >
> > > Excellent!
> > >
> > > Before we can use it I'm afraid you have to contribute it to the
> > > shootout, we can't just skim programs from other places.
> > >
> > > Please send programs to the mailing list or send them using the
> message
> > > form or email them to igouy2
> > >
> > > http://shootout.alioth.debian.org/faq.php?so...
> > >
> > > best wishes, Isaac
> > >
> >
> > is the input from the form actually received?
>
> Hmmm I'll do a test and see if we receive what we should.

The message form seems to operate just fine.
Contribute programs with the message form or the mailing list or email.

jzakiya

3/21/2005 7:13:00 AM

0

Martin DeMello wrote:
> Here's a first pass at the n body problem in the shootout - I've
tried
> to strike a balance between idiomatic and fast, the main optimisation
> being to remove all object creation from the advance() loop as far as
> possible, in favour of methods that updated an existing object.
>
>
http://shootout.alioth..../benchmark.php?test=nbody&lang=all&so...
>
>
-----------------------------------------------------------------------
>
> include Math
>
> SOLAR_MASS = 4*PI*PI
> DAYS_PER_YEAR = 365.24
>
> Vector3D = Struct.new("Vector3D", :x, :y, :z)
>
> class Vector3D
>
> def *(val)
> Vector3D.new(*self.map {|i| i * val})
> end
>
> def /(val)
> Vector3D.new(*self.map {|i| i / val})
> end
>
> #in-place add with scale
> # a.adds(b, s) -> a += b*s
>
> def adds(other, scale)
> 3.times {|i| self[i] += other[i] * scale}
> end
>
> def subs(other, scale)
> adds(other, -scale)
> end
>
> def magnitude
> d = self.inject(0) {|a,v| a + v*v}
> sqrt(d)
> end
>
> # |self - other|
> def dmag(other)
> sqrt((0...3).inject(0) {|a, i| d = (self[i] - other[i]); a + d *
d})
> end
> end
>
> class Planet
> attr_accessor :pos, :v, :mass
>
> def initialize(x, y, z, vx, vy, vz, mass)
> @pos = Vector3D.new(x, y, z)
> @v = Vector3D.new(vx, vy, vz) * DAYS_PER_YEAR
> @mass = mass * SOLAR_MASS
> end
>
> def distance(other)
> self.pos.dmag(other.pos)
> end
> end
>
> jupiter = Planet.new(
> 4.84143144246472090e+00,
> -1.16032004402742839e+00,
> -1.03622044471123109e-01,
> 1.66007664274403694e-03,
> 7.69901118419740425e-03,
> -6.90460016972063023e-05,
> 9.54791938424326609e-04)
>
> saturn = Planet.new(
> 8.34336671824457987e+00,
> 4.12479856412430479e+00,
> -4.03523417114321381e-01,
> -2.76742510726862411e-03,
> 4.99852801234917238e-03,
> 2.30417297573763929e-05,
> 2.85885980666130812e-04)
>
> uranus = Planet.new(
> 1.28943695621391310e+01,
> -1.51111514016986312e+01,
> -2.23307578892655734e-01,
> 2.96460137564761618e-03,
> 2.37847173959480950e-03,
> -2.96589568540237556e-05,
> 4.36624404335156298e-05)
>
> neptune = Planet.new(
> 1.53796971148509165e+01,
> -2.59193146099879641e+01,
> 1.79258772950371181e-01,
> 2.68067772490389322e-03,
> 1.62824170038242295e-03,
> -9.51592254519715870e-05,
> 5.15138902046611451e-05)
>
> sun = Planet.new(0, 0, 0, 0, 0, 0, 1)
>
> class Array
> def each_pair
> a = []
> each_index {|i|
> ((i+1)...length).each {|j|
> yield at(i), at(j)
> }
> }
> end
> end
>
> bodies = [sun, jupiter, saturn, uranus, neptune]
>
> class << bodies
> def advance(dt)
> mag = m1 = m2 = nil
> each_pair {|b1, b2|
> d = b1.distance(b2)
> mag = dt/(d*d*d)
>
> m1 = b1.mass * mag
> m2 = b2.mass * mag
>
> b1.v.adds(b2.pos, m2)
> b1.v.subs(b1.pos, m2)
> b2.v.adds(b1.pos, m1)
> b2.v.subs(b2.pos, m1)
> }
>
> each {|b| b.pos.adds(b.v, dt)}
> end
>
> def energy
> e = 0
> each {|b| e += 0.5 * b.mass * (b.v.magnitude ** 2) }
> each_pair {|b1, b2| e -= (b1.mass * b2.mass) / b1.distance(b2) }
> e
> end
>
> def offset_momentum
> p = Vector3D.new(0,0,0)
> sun = self[0]
> each {|b| p.adds(b.v, b.mass) }
> sun.v.subs(p, 1.0/sun.mass)
> end
> end
>
> require 'benchmark'
>
> Benchmark.bm {|x|
> x.report {
> bodies.offset_momentum
> puts bodies.energy
> Integer(ARGV[0]).times { bodies.advance(0.01) }
> puts bodies.energy
> }
>

I just sent this to the Shootout list
=====================================================

Here is a much faster nbody Ruby benchmark.
For N=1_000_000 (1 million) the original
code took 41 minutes to execute on my system.
(AMD K-7, 600Mhz, 640MB, Mandrake 10.1 Ofl, Ruby 1.8.2)
This modified code executed the benchmark in 17 minutes.
The modification consists of unrolling the loops in
4 methods in the Vector3D class which do vector math.

This modification probably would speed up all the
dynamic languages (Perl, Python, PHP, etc). For C/C++
with good optimizing compilers, loop unrolling may
already be taking place, but it's something that could
be tested for.

The benchmark originally listed the benchmark
as having an error. However, the original code
ran on my system with no errors.

The "error" was the erroneous execution of the benchmark,
resulting from N set to 1, and not 1 million as required.

Jabari Zakiya

###########################################
# The Computer Language Benchmark Shootout
# http://shootout.alioth....
# nbody Ruby benchmark
#
# original code by Martin DeMello
# modified by Jabari Zakiya 3/20/05

include Math

SOLAR_MASS = 4*PI*PI
DAYS_PER_YEAR = 365.24

Vector3D = Struct.new("Vector3D", :x, :y, :z)

class Vector3D

def *(val)
Vector3D.new(*self.map {|i| i * val})
end

def /(val)
Vector3D.new(*self.map {|i| i / val})
end

#in-place add with scale
# a.adds(b, s) -> a += b*s

def adds(other, scale)
self[0] += other[0]*scale; self[1] += other[1]*scale
self[2] += other[2]*scale
end

def subs(other, scale)
self[0] -= other[0]*scale; self[1] -= other[1]*scale
self[2] -= other[2]*scale
end

def magnitude
x=self[0]; y=self[1]; z=self[2]
sqrt(x*x + y*y + z*z)
end

# |self - other|
def dmag(other)
x=self[0]-other[0]; y=self[1]-other[1]; z=self[2]-other[2]
sqrt(x*x + y*y + z*z)
end
end

class Planet
attr_accessor :pos, :v, :mass

def initialize(x, y, z, vx, vy, vz, mass)
@pos = Vector3D.new(x, y, z)
@v = Vector3D.new(vx, vy, vz) * DAYS_PER_YEAR
@mass = mass * SOLAR_MASS
end

def distance(other)
self.pos.dmag(other.pos)
end
end

jupiter = Planet.new(
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03,
7.69901118419740425e-03,
-6.90460016972063023e-05,
9.54791938424326609e-04)

saturn = Planet.new(
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03,
4.99852801234917238e-03,
2.30417297573763929e-05,
2.85885980666130812e-04)

uranus = Planet.new(
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03,
2.37847173959480950e-03,
-2.96589568540237556e-05,
4.36624404335156298e-05)

neptune = Planet.new(
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03,
1.62824170038242295e-03,
-9.51592254519715870e-05,
5.15138902046611451e-05)

sun = Planet.new(0, 0, 0, 0, 0, 0, 1)

class Array
def each_pair
a = []
each_index {|i|
((i+1)...length).each {|j|
yield at(i), at(j)
}
}
end
end

bodies = [sun, jupiter, saturn, uranus, neptune]

class << bodies
def advance(dt)
mag = m1 = m2 = nil
each_pair {|b1, b2|
d = b1.distance(b2)
mag = dt/(d*d*d)

m1 = b1.mass * mag
m2 = b2.mass * mag

b1.v.adds(b2.pos, m2)
b1.v.subs(b1.pos, m2)
b2.v.adds(b1.pos, m1)
b2.v.subs(b2.pos, m1)
}

each {|b| b.pos.adds(b.v, dt)}
end

def energy
e = 0
each {|b| e += 0.5 * b.mass * (b.v.magnitude ** 2) }
each_pair {|b1, b2| e -= (b1.mass * b2.mass) / b1.distance(b2) }
e
end

def offset_momentum
p = Vector3D.new(0,0,0)
sun = self[0]
each {|b| p.adds(b.v, b.mass) }
sun.v.subs(p, 1.0/sun.mass)
end
end

bodies.offset_momentum
puts bodies.energy
Integer(ARGV[0]).times { bodies.advance(0.01) }
puts bodies.energy

Isaac Gouy

3/21/2005 6:07:00 PM

0

> The modification consists of unrolling the loops in
> 4 methods in the Vector3D class which do vector math.

Manual loop unrolling is one optimization too many.

We have a preference for plain vanilla programs - we're trying to
compare language implementations, not programmers.

jzakiya

3/22/2005 7:09:00 AM

0

Isaac Gouy wrote:
> > The modification consists of unrolling the loops in
> > 4 methods in the Vector3D class which do vector math.
>
> Manual loop unrolling is one optimization too many.
>
> We have a preference for plain vanilla programs - we're trying to
> compare language implementations, not programmers.

I'm a litlle tired, and will respond more fully later, but I felt
a prompt response was needed now.

There is no requirement in any language, or as a paradigm of
coding practice, that a looping structure be applied to every
potential instance where its use is possible. To "unroll" a
"loop" is a coding "optimization" only if you start from the
reference point of the use of a loop structure. If you never
use a loop structure in the first place, and instead perform a
"direct implementation" of a function from the start, then that
is the reference point of further modification.

When engaging in the exercise of "benchmarking" inherent in
that exercise is to identify coding techniques and paradigms
within the idiom of the language being used to perform the
stated tasks as fast as possible.

Benchmarking is not about predetermining an arbitrary coding
structure paradigm and unilaterally applying that paradigm
to a every language, irrespective of the negative consequences
it has to producing the fastest program in that language.

Ruby is a native dynamic interpretive language. A user, to
acquire the highest performance possible from the language, has
to understand the consequences of this fact. One thing this mean
is that a user has to be "the compiler" at times, in order to
squeeze the highest possible performance out of the language.
Ruby is not C/C++, with highly optimized compilers, which do
a lot of the thinking for the programmer to extract performance
from source code.

Thus, as in the original nbody code, you could produce the
magnitude of a 3-dimensional vector as follows:

def magnitude
d = self.inject(0) {|a,v| a + v*v}
sqrt(d)
end

but the original code took 41 minutes to run on my system
(AMD K-7, 600Mhz, 640MB, Mandrake 10.1 Ofl, Ruby 1.8.2)

However, the inject method is not "performance optimum".

So, I first rewrote the looping structure to make it faster:

def magnitude
d = 0.0: (0..2).each {|i| d += self[i]**2}
sqrt(d)
end

and this was even a little faster

def magnitude
d = 0.0; 3.times {|i| d += self[i]**2}
sqrt(d)
end

At this point, by optimizing the most performance efficient
Ruby looping structure, I got the benchmark task down from
41 minutes to 27 minutes. Then the little lightbulb in my
head turned on.

Instead of looking at the task as an exercise in the use of
programming structures, I looked at what was the physics that
was trying to be done. After I realized what the physics
was, I just wrote code to "directly implement" the physics.

def magnitude
x=self[0]; y=self[1]; z=self[2]
sqrt(x*x + y*y + z*z)
end

Not only is this code accurate, its simple, understandable, AND
creates a MUCH faster program, which is the main point for a
benchmark. Using "direct implementation" of just 4 function methods
reduced the revised benchmark (which I posted) time to 17 minutes,
from the 'original code' time of 41 minutes.

Further testing has reduced the time to 15 minutes, using the
following code for the magnitude, tested to be the fastest so far.

def magnitude
sqrt(self[0]**2 + self[1]**2 + self[2]**2)
end

Besides executing the fastest in Ruby 1.8.2, you can't
produce code any shorter and simpler than this.

So by what codified set of programmnig rules can anyone say, with
sustainable validity, that this coding paradigm is inappropriate?

In fact, in the "real world" where money, time, efficiency, and
people's lives matter, "direct implementation" of functions, in
my experience, is standard procedure, especially where speed
matters. This is especially true with languages such as Forth,
my native software language.

Now the Ruby nbody benchmark performs 1 million iterations in
15 minutes instead of 41 minutes, which is 2.5 faster than the
original code!

Ruby is a great language to get real work done with. It isn't
natively the fastest, but it needn't be naively coded to create
unnecessarily slow performance.

I've just shown one simple technique to speed up Ruby 1.8.2.
Hopefully, with Ruby 2.0 and beyond, native performance will
inherently increase. Until then, if performance matters, then
you have to think a little bit about what you are really trying
to do, and do it the "best" way to optimize Ruby performance.

Thus, I disagree that benchmarks are about applying some
arbitrary programming paradigm to a set of languages, just so
the "look" of the programs are similar. Benchmarks should
illustrate how a given language can be used to perform a
given task (the benchmark) in that language, particularly
using the best programming techniques and idioms unique to
that language.

Thus, to me, the primary essence of benchmarking is comparing
how different languages can be uniquely applied to optimally
perform the same tasks, and comparing those results.

I'll expand more on these points in the future, but I hope these
comments explain my point-of-view, and reasoning, on this issue.

Jabari Zakiya

Isaac Gouy

3/23/2005 4:30:00 PM

0

> Thus, I disagree that benchmarks are about applying some
> arbitrary programming paradigm to a set of languages, just so
> the "look" of the programs are similar.

You're welcome to your opinion - and we're happy to include the program
as an 'alternative'.

Note: The C# Mono #2 program is listed as an alternative because a
member of the Mono development team wanted a plain vanilla comparison
between C# Mono and other languages - hand-optimizing index-access with
a local variable ruined that comparison.

Randy Kramer

3/23/2005 5:36:00 PM

0

On Wednesday 23 March 2005 11:34 am, Isaac Gouy wrote:
> > Thus, I disagree that benchmarks are about applying some
> > arbitrary programming paradigm to a set of languages, just so
> > the "look" of the programs are similar.
>
> You're welcome to your opinion - and we're happy to include the program
> as an 'alternative'.

Just to inject my $.02, I'd say both types of benchmarks are useful. IMHO,
it's unlikely you'll find a benchmark that does exactly what you want. If
you know you have to loop, a benchmark that compares looping in several
languages is useful. On the other hand, if you are not aware of some more
elegant approach (than looping, in this case) that might apply to your
problem, and might be faster as well as more elegant, the "different
approach" benchmark is useful.

Randy Kramer