Python 辞書と If 文の速度の違い 質問する

Python 辞書と If 文の速度の違い 質問する

コンパイル時に最適化できるため、C++ では switch ケースの方が if else よりも高速であるというリンクをいくつか見つけました。その後、辞書を使用する方が If ステートメントよりも高速になる可能性があるという提案もいくつか見つかりました。ただし、ほとんどの会話は誰かの仕事に関するもので、結局はコードの他の部分を最初に最適化する必要があり、何百万もの if else を実行しない限りは問題にならないという議論に終わります。なぜそうなるのか説明できる人はいますか?

たとえば、Python コードに絶えずストリームされる 100 個の一意の数字があるとします。その数字が何であるかを確認し、何かを実行したいとします。そのため、大量の if else を実行するか、各数字を辞書に入れることができます。議論のために、これは単一のスレッドであるとします。

Python と低レベルの実行の間のレイヤーを理解していて、これがどのように機能するかを説明できる人はいますか?

ありがとう :)

ベストアンサー1

しかし、会話のほとんどは誰かの仕事に関するもので、結局はコードの他の部分をまず最適化するべきで、何百万もの if else を実行しない限りは問題にならないという議論に終わります。なぜそうなるのか説明できる人はいますか?

一般的に、本当に必要な場合、つまりプログラムのパフォーマンスが使用できないほど遅い場合のみ、コードの最適化を行う必要があります。

このような場合は、プロファイラを使用して、実際にどの部分が最も問題を引き起こしているかを判断する必要があります。Pythonの場合、cプロフィールこのモジュールはこれに最適です。

Python と低レベルの実行の間のレイヤーを理解していて、これがどのように機能するかを説明できる人はいますか?

コードがどのように実行されるかを知りたい場合は、ディスモジュール。

簡単な例を挙げますと...

import dis

# Here are the things we might want to do
def do_something_a():
    print 'I did a'


def do_something_b():
    print 'I did b'


def do_something_c():
    print 'I did c'


# Case 1
def f1(x):
    if x == 1:
        do_something_a()
    elif x == 2:
        do_something_b()
    elif x == 3:
        do_something_c()


# Case 2
FUNC_MAP = {1: do_something_a, 2: do_something_b, 3: do_something_c}
def f2(x):
    FUNC_MAP[x]()


# Show how the functions execute
print 'Case 1'
dis.dis(f1)
print '\n\nCase 2'
dis.dis(f2)

...出力は...

Case 1
 18           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (1)
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_FALSE       22

 19          12 LOAD_GLOBAL              0 (do_something_a)
             15 CALL_FUNCTION            0
             18 POP_TOP
             19 JUMP_FORWARD            44 (to 66)

 20     >>   22 LOAD_FAST                0 (x)
             25 LOAD_CONST               2 (2)
             28 COMPARE_OP               2 (==)
             31 POP_JUMP_IF_FALSE       44

 21          34 LOAD_GLOBAL              1 (do_something_b)
             37 CALL_FUNCTION            0
             40 POP_TOP
             41 JUMP_FORWARD            22 (to 66)

 22     >>   44 LOAD_FAST                0 (x)
             47 LOAD_CONST               3 (3)
             50 COMPARE_OP               2 (==)
             53 POP_JUMP_IF_FALSE       66

 23          56 LOAD_GLOBAL              2 (do_something_c)
             59 CALL_FUNCTION            0
             62 POP_TOP
             63 JUMP_FORWARD             0 (to 66)
        >>   66 LOAD_CONST               0 (None)
             69 RETURN_VALUE


Case 2
 29           0 LOAD_GLOBAL              0 (FUNC_MAP)
              3 LOAD_FAST                0 (x)
              6 BINARY_SUBSCR
              7 CALL_FUNCTION            0
             10 POP_TOP
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE

...どの関数が最も多くの命令を実行する必要があるかを確認するのは非常に簡単です。

実際にどちらが速いかは、コードをプロファイリングして確認する必要があります。

おすすめ記事