sys.intern()
は、内容が同じ「等価」な文字列に対して実行環境上で「同一」の文字列を返す。返された文字列どうしは==
ではなくis
で一致するようになる。
特に文字列が長い場合、 sys.intern()
で大幅な高速化を期待できるはずだ。以下に例を示す。
intern_test.py
import sys
import timeit
def comp1(a, b):
return a == b
def comp2(a, b):
return a is b
for n in [10000, 50000]:
a = ''.join([str(s) for s in range(0, n)])
b = ''.join([str(s) for s in range(0, n)])
ia = sys.intern(a)
ib = sys.intern(b)
print("--{}--".format(n))
print("comp1(a, b)", comp1(a, b),
timeit.timeit("comp1(a, b)", globals=globals()), sep='\t')
print("comp2(a, b)", comp2(a, b),
timeit.timeit("comp2(a, b)", globals=globals()), sep='\t')
print("comp1(ia, ib)", comp1(ia, ib),
timeit.timeit("comp1(ia, ib)", globals=globals()), sep='\t')
print("comp2(ia, ib)", comp2(ia, ib),
timeit.timeit("comp2(ia, ib)", globals=globals()), sep='\t')
Python 3.6.2 での実行例を示す。
$ python intern_test.py
--10000--
comp1(a, b) True 1.5900884549773764
comp2(a, b) False 0.12032010598341003
comp1(ia, ib) True 0.13831643099547364
comp2(ia, ib) True 0.13083625899162143
--50000--
comp1(a, b) True 11.056225399981486
comp2(a, b) False 0.11997383600100875
comp1(ia, ib) True 0.13671555201290175
comp2(ia, ib) True 0.12875197199173272
comp1(a, b)
に対してcomp2(ia, ib)
は高速になっていることが分かる。また、==
は予想通りサイズに対してO(n)で遅くなっている気配がするのに対して is
は O(1)。
ところでcomp1(ia, ib)
(ia == ib
)の結果も十分に高速になっているが、comp2(ia, ib)
(ia is ib
)と比較すると10ms弱程度遅い。if分岐か何かだろうか。
追記 (2017-09-01): Python 3.6.2 を用いて内容を修正。
追記 (2017-09-04): 文面を少し修正。