からこのページ、 私達はことを知っています:
連鎖比較は
and
演算子を使用するよりも高速です。x < y < z
の代わりに と記述しますx < y and y < z
。
ただし、次のコード スニペットをテストすると、異なる結果が得られました。
$ python -m timeit "x = 1.2" "y = 1.3" "z = 1.8" "x < y < z"
1000000 loops, best of 3: 0.322 usec per loop
$ python -m timeit "x = 1.2" "y = 1.3" "z = 1.8" "x < y and y < z"
1000000 loops, best of 3: 0.22 usec per loop
$ python -m timeit "x = 1.2" "y = 1.3" "z = 1.1" "x < y < z"
1000000 loops, best of 3: 0.279 usec per loop
$ python -m timeit "x = 1.2" "y = 1.3" "z = 1.1" "x < y and y < z"
1000000 loops, best of 3: 0.215 usec per loop
x < y and y < z
はよりも速いようですx < y < z
。なぜ?
このサイトのいくつかの投稿を検索した後(これです) のキーは「1 回だけ評価される」ことだとわかっていますx < y < z
が、まだ混乱しています。さらに学習するために、 を使用してこれらの 2 つの関数を逆アセンブルしましたdis.dis
。
import dis
def chained_compare():
x = 1.2
y = 1.3
z = 1.1
x < y < z
def and_compare():
x = 1.2
y = 1.3
z = 1.1
x < y and y < z
dis.dis(chained_compare)
dis.dis(and_compare)
出力は次のようになります。
## chained_compare ##
4 0 LOAD_CONST 1 (1.2)
3 STORE_FAST 0 (x)
5 6 LOAD_CONST 2 (1.3)
9 STORE_FAST 1 (y)
6 12 LOAD_CONST 3 (1.1)
15 STORE_FAST 2 (z)
7 18 LOAD_FAST 0 (x)
21 LOAD_FAST 1 (y)
24 DUP_TOP
25 ROT_THREE
26 COMPARE_OP 0 (<)
29 JUMP_IF_FALSE_OR_POP 41
32 LOAD_FAST 2 (z)
35 COMPARE_OP 0 (<)
38 JUMP_FORWARD 2 (to 43)
>> 41 ROT_TWO
42 POP_TOP
>> 43 POP_TOP
44 LOAD_CONST 0 (None)
47 RETURN_VALUE
## and_compare ##
10 0 LOAD_CONST 1 (1.2)
3 STORE_FAST 0 (x)
11 6 LOAD_CONST 2 (1.3)
9 STORE_FAST 1 (y)
12 12 LOAD_CONST 3 (1.1)
15 STORE_FAST 2 (z)
13 18 LOAD_FAST 0 (x)
21 LOAD_FAST 1 (y)
24 COMPARE_OP 0 (<)
27 JUMP_IF_FALSE_OR_POP 39
30 LOAD_FAST 1 (y)
33 LOAD_FAST 2 (z)
36 COMPARE_OP 0 (<)
>> 39 POP_TOP
40 LOAD_CONST 0 (None)
x < y and y < z
はよりも逆アセンブルされたコマンドが少ないようです。よりも高速であるとx < y < z
考えたほうがよいでしょうか?x < y and y < z
x < y < z
Intel(R) Xeon(R) CPU E5640 @ 2.67GHz で Python 2.7.6 を使用してテストされました。
ベストアンサー1
違いは、 in はx < y < z
y
1 回しか評価されないことです。 y が変数の場合は大きな違いはありませんが、計算に時間がかかる関数呼び出しの場合は違いがあります。
from time import sleep
def y():
sleep(.2)
return 1.3
%timeit 1.2 < y() < 1.8
10 loops, best of 3: 203 ms per loop
%timeit 1.2 < y() and y() < 1.8
1 loops, best of 3: 405 ms per loop