is
と==
の違い
==
は、「同じ値かどうか」で判断するのに対し、is
は「同じオブジェクトかどうか」で判断します。
例えば、以下の例で言うと、
>>> a = "hello"
>>> b = "hello"
どちらも同じ値を持つオブジェクトのため、==
で比較した場合True
を返します。
>>> a == b
True
が、is
は「同じオブジェクトか」で判断します
Pythonでは、オブジェクトを生成するとそのオブジェクトに一意の番号が振られます。is
は、その番号で判別します。
番号はid()
で確認できます。
>>> id(a)
2827074142256
>>> id(b)
2827074145520
>>> a is b
False
isinstance
でも型を比較できる
isinstance
はオブジェクトのクラスを比較する関数です。
別のクラスを継承していた場合、親クラスと比較してもTrue
を返します
>>> class customint(int):
... pass
...
>>> c = customint()
>>> type(c) == int
False
>>> type(c) is int
False
>>> isinstance(c, int)
True
実行時間を計測する
やること
それぞれの関数を10,000,000回(1千万回)実行し、実行時間を計測します
これを10回繰り返し、平均を算出します
参考として、何もせずに10,000,000回ループする関数も実行します
ソースコード
#!/usr/bin/env python3
# coding: utf-8
from time import time
intvar = 0
n = 10 ** 7
def gettime(name, num=10):
"""
10回実行し、実行時間を計測し、平均を出す
"""
def func(fn):
def wrapper(*args, **kwargs):
strat_t = time()
for a in range(num):
fn(*args, **kwargs)
dur = (time() - strat_t) / 10
print(name, "\t:", dur)
return wrapper
return func
@gettime("simple\t")
def simple():
for x in range(n):
pass
@gettime("equal\t")
def equal():
for x in range(n):
res = type(intvar) == int
if type(intvar) == True:
pass
@gettime("is\t")
def iscompare():
for x in range(n):
res = type(intvar) is int
@gettime("isinstance")
def isinstancecompare():
for x in range(n):
res = isinstance(intvar, int)
if __name__ == '__main__':
simple()
equal()
iscompare()
isinstancecompare()
結果
(単位:秒)
実行環境 | Windows 10 Intel Core i7-8550U @ 1.80GHz RAM:16GB |
さくらのVPS(v3) 1G |
---|---|---|
空ループ | 0.1508335590362549 | 0.37562224864959715 |
== |
0.8364578723907471 | 1.9130330801010131 |
is |
0.8253042459487915 | 1.799116063117981 |
isinstance |
0.5259079456329345 | 1.3679522275924683 |
考察
実行時間は、
==
> is
>>> isinstance
という感じになりました。
なので、
- 継承を考慮して型比較をしたい
- 継承とかよくわかんないけど、とにかく速度を求めたい
場合にはisinstance
を、
- 継承を無視して型比較をしたい
場合にはis
を使いましょう。
感想
デコレーター初めて使ったけどめっちゃ便利やん