Skip to content

Instantly share code, notes, and snippets.

@timo

timo/README Secret

Last active September 13, 2015 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timo/b52c874c07d27d631bb3 to your computer and use it in GitHub Desktop.
Save timo/b52c874c07d27d631bb3 to your computer and use it in GitHub Desktop.
nbody benchmark
just run this with a parameter like 30000 to get a good few runs in.
the native version of this will take longer - on my machine they run in:
objects: 9573.21ms - 99.83% jitted frame entries - 110 GC runs
native : 11998.7ms - 77.3% jitted frame entries - 340 GC runs
without the .Int after $*ARGS[0], we get these numbers:
objects: 11996.5ms - 96.43 jitted frame entries - 147 GC runs
native : 14573.28ms - 75.57 jitted frame entries - 379 GC runs
#
# The Great Computer Language Shootout
# http://shootout.alioth.debian.org/
#
# contributed by Christoph Bauer
# converted into Perl by Márton Papp
#
my num $pi = 3.141592653589793e0;
my num $solar_mass = (4e0 * $pi * $pi).Num;
my num $days_per_year = 365.24e0;
class Body is rw {
has num ($.x, $.y, $.z);
has num ($.vx, $.vy, $.vz);
has num $.mass;
}
sub advance (@bodies is rw, num $dt)
{
my int ($i, $j);
my $nbodies = @bodies.elems;
loop ($i = 0; $i < $nbodies; $i++) {
my Body $b = @bodies[$i];
my Body $b2;
my num ($dx, $dy,$dz,$distance,$mag);
my num ($bmass, $b2massmag);
$bmass = $b.mass;
loop ($j = $i + 1; $j < $nbodies; $j++) {
$b2 = @bodies[$j];
$dx = $b.x - $b2.x;
$dy = $b.y - $b2.y;
$dz = $b.z - $b2.z;
$distance = sqrt($dx * $dx + $dy * $dy + $dz * $dz);
$mag = $dt / ($distance * $distance * $distance);
$b2massmag = $b2.mass * $mag;
$b.vx -= $dx * $b2massmag;
$b.vy -= $dy * $b2massmag;
$b.vz -= $dz * $b2massmag;
$b2.vx += $dx * $bmass * $mag;
$b2.vy += $dy * $bmass * $mag;
$b2.vz += $dz * $bmass * $mag;
}
}
loop ($i = 0; $i < $nbodies; $i++) {
my $b = @bodies[$i];
$b.x += $dt * $b.vx;
$b.y += $dt * $b.vy;
$b.z += $dt * $b.vz;
}
}
sub energy(@bodies is readonly)
{
my num $e;
my int ($i, $j);
my int $nbodies = @bodies.elems;
$e = 0.0e0;
loop ($i = 0; $i < $nbodies; $i++) {
my $b = @bodies[$i];
$e += 0.5 * $b.mass * ($b.vx * $b.vx + $b.vy * $b.vy + $b.vz * $b.vz);
my num ($dx,$dy,$dz,$distance);
loop ($j = $i + 1; $j < $nbodies; $j++) {
my $b2 = @bodies[$j];
$dx = $b.x - $b2.x;
$dy = $b.y - $b2.y;
$dz = $b.z - $b2.z;
$distance = sqrt($dx * $dx + $dy * $dy + $dz * $dz);
$e -= ($b.mass * $b2.mass) / $distance;
}
}
return $e;
}
sub offset_momentum(@bodies is rw)
{
my num $px = 0.0e0;
my num $py = 0.0e0;
my num $pz = 0.0e0;
my int $i;
my int $nbodies = @bodies.elems;
my num $bmass;
loop ($i = 0; $i < $nbodies; $i++) {
my $body = @bodies[$i];
$bmass = $body.mass;
$px += $body.vx * $bmass;
$py += $body.vy * $bmass;
$pz += $body.vz * $bmass;
}
@bodies[0].vx = - $px / $solar_mass;
@bodies[0].vy = - $py / $solar_mass;
@bodies[0].vz = - $pz / $solar_mass;
}
my @bodies =
Body.new( # sun
x => 0e0, y => 0e0,z => 0e0,vx => 0e0, vy => 0e0,vz => 0e0, mass=> $solar_mass
),
Body.new( # jupiter
x => 4.84143144246472090e+00,
y => -1.16032004402742839e+00,
z => -1.03622044471123109e-01,
vx => 1.66007664274403694e-03 * $days_per_year,
vy => 7.69901118419740425e-03 * $days_per_year,
vz => -6.90460016972063023e-05 * $days_per_year,
mass=> 9.54791938424326609e-04 * $solar_mass
),
Body.new( #saturn
x => 8.34336671824457987e+00,
y => 4.12479856412430479e+00,
z => -4.03523417114321381e-01,
vx => -2.76742510726862411e-03 * $days_per_year,
vy => 4.99852801234917238e-03 * $days_per_year,
vz => 2.30417297573763929e-05 * $days_per_year,
mass=> 2.85885980666130812e-04 * $solar_mass
),
Body.new( #uranus
x => 1.28943695621391310e+01,
y => -1.51111514016986312e+01,
z => -2.23307578892655734e-01,
vx => 2.96460137564761618e-03 * $days_per_year,
vy => 2.37847173959480950e-03 * $days_per_year,
vz => -2.96589568540237556e-05 * $days_per_year,
mass=> 4.36624404335156298e-05 * $solar_mass
),
Body.new( #neptune
x => 1.53796971148509165e+01,
y => -2.59193146099879641e+01,
z => 1.79258772950371181e-01,
vx => 2.68067772490389322e-03 * $days_per_year,
vy => 1.62824170038242295e-03 * $days_per_year,
vz => -9.51592254519715870e-05 * $days_per_year,
mass=> 5.15138902046611451e-05 * $solar_mass
)
;
my int $n = @*ARGS[0].Int;
offset_momentum(@bodies);
printf("%.9f\n", energy(@bodies));
loop (my int $i = 1; $i <= $n; $i++)
{
advance(@bodies, 0.01e1);
}
printf("%.9f\n", energy(@bodies));
#
# The Great Computer Language Shootout
# http://shootout.alioth.debian.org/
#
# contributed by Christoph Bauer
# converted into Perl by Márton Papp
#
my $pi = 3.141592653589793;
my $solar_mass =(4 * $pi * $pi);
my $days_per_year =365.24;
class Body is rw {
has ($.x, $.y, $.z);
has ($.vx, $.vy, $.vz);
has $.mass;
}
sub advance (@bodies is rw, $dt)
{
my ($i, $j);
my $nbodies = @bodies.elems;
loop ($i = 0; $i < $nbodies; $i++) {
my Body $b = @bodies[$i];
my Body $b2;
my ($dx, $dy,$dz,$distance,$mag);
my ($bmass, $b2massmag);
$bmass = $b.mass;
loop ($j = $i + 1; $j < $nbodies; $j++) {
$b2 = @bodies[$j];
$dx = $b.x - $b2.x;
$dy = $b.y - $b2.y;
$dz = $b.z - $b2.z;
$distance = sqrt($dx * $dx + $dy * $dy + $dz * $dz);
$mag = $dt / ($distance * $distance * $distance);
$b2massmag = $b2.mass * $mag;
$b.vx -= $dx * $b2massmag;
$b.vy -= $dy * $b2massmag;
$b.vz -= $dz * $b2massmag;
$b2.vx += $dx * $bmass * $mag;
$b2.vy += $dy * $bmass * $mag;
$b2.vz += $dz * $bmass * $mag;
}
}
loop ($i = 0; $i < $nbodies; $i++) {
my $b = @bodies[$i];
$b.x += $dt * $b.vx;
$b.y += $dt * $b.vy;
$b.z += $dt * $b.vz;
}
}
sub energy(@bodies is readonly)
{
my $e;
my ($i, $j);
my $nbodies = @bodies.elems;
$e = 0.0e0;
loop ($i = 0; $i < $nbodies; $i++) {
my $b = @bodies[$i];
$e += 0.5 * $b.mass * ($b.vx * $b.vx + $b.vy * $b.vy + $b.vz * $b.vz);
my ($dx,$dy,$dz,$distance);
loop ($j = $i + 1; $j < $nbodies; $j++) {
my $b2 = @bodies[$j];
$dx = $b.x - $b2.x;
$dy = $b.y - $b2.y;
$dz = $b.z - $b2.z;
$distance = sqrt($dx * $dx + $dy * $dy + $dz * $dz);
$e -= ($b.mass * $b2.mass) / $distance;
}
}
return $e;
}
sub offset_momentum(@bodies is rw)
{
my $px = 0.0e0;
my $py = 0.0e0;
my $pz = 0.0e0;
my $i;
my $nbodies = @bodies.elems;
my $bmass;
loop ($i = 0; $i < $nbodies; $i++) {
my $body = @bodies[$i];
$bmass = $body.mass;
$px += $body.vx * $bmass;
$py += $body.vy * $bmass;
$pz += $body.vz * $bmass;
}
@bodies[0].vx = - $px / $solar_mass;
@bodies[0].vy = - $py / $solar_mass;
@bodies[0].vz = - $pz / $solar_mass;
}
my @bodies =
Body.new( # sun
x => 0e0, y => 0e0,z => 0e0,vx => 0e0, vy => 0e0,vz => 0e0, mass=> $solar_mass
),
Body.new( # jupiter
x => 4.84143144246472090e+00,
y => -1.16032004402742839e+00,
z => -1.03622044471123109e-01,
vx => 1.66007664274403694e-03 * $days_per_year,
vy => 7.69901118419740425e-03 * $days_per_year,
vz => -6.90460016972063023e-05 * $days_per_year,
mass=> 9.54791938424326609e-04 * $solar_mass
),
Body.new( #saturn
x => 8.34336671824457987e+00,
y => 4.12479856412430479e+00,
z => -4.03523417114321381e-01,
vx => -2.76742510726862411e-03 * $days_per_year,
vy => 4.99852801234917238e-03 * $days_per_year,
vz => 2.30417297573763929e-05 * $days_per_year,
mass=> 2.85885980666130812e-04 * $solar_mass
),
Body.new( #uranus
x => 1.28943695621391310e+01,
y => -1.51111514016986312e+01,
z => -2.23307578892655734e-01,
vx => 2.96460137564761618e-03 * $days_per_year,
vy => 2.37847173959480950e-03 * $days_per_year,
vz => -2.96589568540237556e-05 * $days_per_year,
mass=> 4.36624404335156298e-05 * $solar_mass
),
Body.new( #neptune
x => 1.53796971148509165e+01,
y => -2.59193146099879641e+01,
z => 1.79258772950371181e-01,
vx => 2.68067772490389322e-03 * $days_per_year,
vy => 1.62824170038242295e-03 * $days_per_year,
vz => -9.51592254519715870e-05 * $days_per_year,
mass=> 5.15138902046611451e-05 * $solar_mass
)
;
my $n = @*ARGS[0].Int;
offset_momentum(@bodies);
printf("%.9f\n", energy(@bodies));
loop (my $i = 1; $i <= $n; $i++)
{
advance(@bodies, 0.01e1);
}
printf("%.9f\n", energy(@bodies));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment