Optimization sequence:
Source code with minor changes
import math, random, time
num = 1000000
random.seed (0x7126434a2ea2a259e9f4196cbb343b1e6d4c2fc8)
pt_list = []
rand_list = []
for i in range(num):
pt = []
for j in range(3):
pt.append(random.random())
pt_list.append(pt)
for i in range(num):
rand_list.append(random.randint(0, num - 1))
beg_time = time.clock()
dist = 0
for i in range(num):
pt0 = pt_list[i]
ri = rand_list[i]
pt1 = pt_list[ri]
val = 0
for j in range(3):
val += (pt0[j] - pt1[j]) ** 2
val = math.sqrt(val)
dist += val
end_time = time.clock()
elap_time = (end_time - beg_time)
print elap_time
print dist
Optimization # 1: Put the code in a function.
The first optimization (not shown) is to insert all the code except importinto the function. This simple change provides a 36% increase in performance on my computer.
Optimization # 2: Release the statement **.
pow(d,2) C-, , C. python. Python ** ; x**2 x*x. , , . , d*d, . :
for i in range(num):
pt0 = pt_list[i]
ri = rand_list[i]
pt1 = pt_list[ri]
val = 0
for j in range(3):
d = pt0[j] - pt1[j]
val += d*d
val = math.sqrt(val)
dist += val
# 3: pythonic.
Python , C-. .
import math, random, time, itertools
def main (num=1000000) :
sqrt = math.sqrt
random.seed (0x7126434a2ea2a259e9f4196cbb343b1e6d4c2fc8)
def random_point () :
return [random.random(), random.random(), random.random()]
def random_index () :
return random.randint(0, num-1)
pt_list = [random_point() for i in xrange(num)]
rand_pts = [pt_list[random_index()] for i in xrange(num)]
beg_time = time.clock()
dist = 0
for (pt0, pt1) in itertools.izip (pt_list, rand_pts) :
d0 = pt0[0]-pt1[0]
d1 = pt0[1]-pt1[1]
d2 = pt0[2]-pt1[2]
dist += sqrt(d0*d0 + d1*d1 + d2*d2)
end_time = time.clock()
elap_time = (end_time - beg_time)
print elap_time
print dist
Update
# 4, numpy
1/40- . , C, .
"Mondo slow". , . numpy. , , numpy # 3.
: numpy, .
import numpy, random, time
def main (num=1000000) :
random.seed (0x7126434a2ea2a259e9f4196cbb343b1e6d4c2fc8)
def random_point () :
return [random.random(), random.random(), random.random()]
def random_index () :
return random.randint(0, num-1)
pt_list = numpy.array([random_point() for i in xrange(num)])
rand_pts = pt_list[[random_index() for i in xrange(num)],:]
beg_time = time.clock()
dist = numpy.sum ((numpy.sum ((pt_list-rand_pts)**2, axis=1))**0.5)
end_time = time.clock()
elap_time = (end_time - beg_time)
print elap_time
print dist