n-body problem at shootout.alioth.debian.org

skip at pobox.com skip at pobox.com
Fri Oct 6 16:38:54 EDT 2006


    Skip> I took the original version, tweaked it slightly (probably did
    Skip> about the same things as Python #2, I didn't look).  For N ==
    Skip> 200,000 the time went from 21.94s (user+sys) to 17.22s.  Using
    Skip> psyco and binding just the advance function on my improved version
    Skip> improved that further to 6.48s.  I didn't have the patience to run
    Skip> larger values of N.  Diff appended.

Ah, wait a moment.  One more tweak.  Make the body class a psyco class.
That improves the runtime to 3.02s.  Diff appended.

Skip

% diff -u nbody.py.~1~ nbody.py
--- nbody.py.~1~        2006-10-06 15:13:31.636675000 -0500
+++ nbody.py    2006-10-06 15:35:36.619976000 -0500
@@ -5,28 +5,31 @@
 # contributed by Kevin Carson

 import sys
+import psyco
+import psyco.classes

 pi = 3.14159265358979323
 solar_mass = 4 * pi * pi
 days_per_year = 365.24

-class body :
+class body(psyco.classes.psyobj):
     pass

 def advance(bodies, dt) :
-    for i in xrange(len(bodies)) :
+    nbodies = len(bodies)
+    for i in xrange(nbodies) :
         b = bodies[i]

-        for j in xrange(i + 1, len(bodies)) :
+        for j in xrange(i + 1, nbodies) :
             b2 = bodies[j]

             dx = b.x - b2.x
             dy = b.y - b2.y
             dz = b.z - b2.z
-            distance = (dx**2 + dy**2 + dz**2)**0.5
-
-            b_mass_x_mag = dt * b.mass / distance**3
-            b2_mass_x_mag = dt * b2.mass / distance**3
+            dsqr = (dx*dx + dy*dy + dz*dz)
+            dtd3 = dt / dsqr ** 1.5
+            b_mass_x_mag = dtd3 * b.mass
+            b2_mass_x_mag = dtd3 * b2.mass

             b.vx -= dx * b2_mass_x_mag
             b.vy -= dy * b2_mass_x_mag
@@ -39,6 +42,7 @@
         b.x += dt * b.vx
         b.y += dt * b.vy
         b.z += dt * b.vz
+psyco.bind(advance)

 def energy(bodies) :
     e = 0.0



More information about the Python-list mailing list