Skip to content
Pull request Compare This branch is 159 commits behind jafingerhut:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
..
Failed to load latest commit information.
README
batch.sh
clj-compile.sh
clj-run.sh
ghc-compile.sh
ghc-run.sh
java-compile.sh
java-run.sh
nbody.clj-1.clj
nbody.clj-10.clj
nbody.clj-11.clj
nbody.clj-12.clj
nbody.clj-13.clj
nbody.clj-14.clj
nbody.clj-2.clj
nbody.clj-3.clj
nbody.clj-4.clj
nbody.clj-5.clj
nbody.clj-6.clj
nbody.clj-7.clj
nbody.clj-8.clj
nbody.clj-9.clj
nbody.ghc
nbody.java-2.java
nbody.jruby-2.jruby
nbody.perl
nbody.sbcl
nbody.sbcl_compile
nbody.sbcl_run
nbody.scala
sbcl-compile.sh
sbcl-run.sh
scala-compile.sh
scala-run.sh

README

clj-5

Fairly straightforward Clojure version, using Clojure maps and
vectors.  All immutable data structures, no Java data structs.


clj-6

Based on clj-5, with many speed improvements:

+ It uses the new transient/assoc!/conj!/persistent! functions for
  Clojure vectors, so you need a pretty new copy of Clojure if you
  want to run it yourself.

+ Make separate vectors for each "attribute" of a body in motion, i.e.
  a separate vector of positions, a vector of velocities, etc.,
  instead of using maps.

+ Use loop/recur almost everywhere it makes sense.  I still have a few
  map calls in the function 'energy' and the functions it calls, and
  maybe in the init code, but that is only done twice and once during
  the whole execution, respectively, versus advance which is called
  50,000,000 times in the long version of the benchmark.


clj-7

Fairly similar to clj-6, except it uses mutable Java arrays of doubles
for representing the mass, position, and velocities of the bodies.

Uses loop/recur everywhere in the inner loop that clj-6 does.

Surprisingly, it isn't nearly as fast as clj-6.  It turns out
aset-double is slow.  See changes made from this to clj-8 version, and
the dramatic speedup it provides.


clj-8

OK, very little change from the source of clj-7, but a big improvement
in performance.  Don't use aset-double.  Use aset and type hints to
avoid reflection.


clj-9

Same as clj-8, but with a few small tweaks inside of function
bodies-update-velocities!

+ Added let binding for delta-t with type hint (doublt delta-t).  This
  didn't make any noticeable difference in run time.

+ Removed lots of (double ...) type hints from the inner let.  No
  noticeable difference in run time.

+ Changed expressions for dist-squared and mag so that they used at
  most 2 operands per mathematical operation rather than the 3
  operands they had before.  This reduced run time to 1/3 of what it
  was before.  Huge improvement.


clj-10

Same as clj-9, but change the bodies parameter to advance! and its
call children to a Java array of java.lang.Object's, instead of a
Clojure vector.  Only about 7% less run time than clj-9, but it is
noticeable.


clj-11

Same as clj-10, but change order of operations for calculating mag so
there is one multiplication and one division, instead of two
divisions.  This matches the Java program more closely, and apparently
the multiply is faster on my hardware, at least.

Also just copy and paste the bodies of the two functions called by
advance! into advance! itself, i.e. by-hand inlining.

About 5% faster than clj-10.
Something went wrong with that request. Please try again.