バイナリ法ってなんとなく美しくなくて嫌いなのだが、ジョギングしながらぼんやり考えていたら、再帰なら割ときれいにかけることに気がついた。
import timedef pow(a, n):
if n > 1:
b = pow(a, n >> 1)
if n & 1: # odd
return a * b * b
else:
return b * b
else:
return an = 100000
t1 = time.clock()
a = 10**n
t2 = time.clock()
b = pow(10, n)
t3 = time.clock()
微妙に**を使うより速い。
ところで、掛け算は同じ数字同士でするとそうでない場合に比べて速いはずである。
(ax + b) * (cx + d) = acx2 + (ad + bc)x + bd
(ax + b) * (ax + b) = a2x2 + (ab + ab)x + b2
上で掛け算が一つ減っている。
import timen = 100000
a = 10 ** n
b = a - 1t1 = time.clock()
c = a * a
t2 = time.clock()
d = a * b
t3 = time.clock()print "%.4fs %.4fs" % (t2 - t1, t3 - t2)
0.1980s 0.3219s
確かに速くなる。しかし、
import timen = 100000
a = 10 ** n
b = a - 1
e = b + 1t1 = time.clock()
c = a * e
t2 = time.clock()
d = a * b
t3 = time.clock()print "%.4fs %.4fs" % (t2 - t1, t3 - t2)
0.3216s 0.3249s
同じ変数でないと速くならないらしい。正確には、変数は違ってもいいが、アドレスは同じでなければならないらしい。