趣味で計算流砂水理

Computational Sediment Hydraulics for Fun

pythonの関数で複数の戻り値を設けた場合の型による速度比較

勉強会で話が出たので整理しました。



速度比較

 複数の戻り値をタプルとディクショナリで戻す場合の速度を比較してみました。

一応私のPCのスペックです。

ノートPCのスペック : VAIO Pro PG - 趣味で計算流砂水理

  • タプル
def returntuple(num):
    A, B, C, D, E = float(0), float(0), float(0), float(0), float(0)
    
    for _ in range(num):
        A += 1.1
        B += 1.11
        C += 1.111
        D += 1.1111
        E += 1.11111
    
    return A, B, C, D, E
%%timeit
returntuple(10000)

1.27 ms ± 33.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

  • ディクショナリ
def returndic(num):
    A, B, C, D, E = float(0), float(0), float(0), float(0), float(0)
    
    for _ in range(num):
        A += 1.1
        B += 1.11
        C += 1.111
        D += 1.1111
        E += 1.11111
    
    return {'A':A, 'B':B, 'C':C, 'D':D, 'E':E}
%%timeit
returndic(10000)

1.32 ms ± 29.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

両者の速度はほとんど変わらない。

numba.jit最適化環境での速度比較

次にnumba.jit最適化時の速度を比較しました。

  • 参考:numba.jitとは

computational-sediment-hyd.hatenablog.jp

computational-sediment-hyd.hatenablog.jp

  • タプル
from numba import jit
@jit(nopython=True)
def returntuple(num):
    A, B, C, D, E = float(0), float(0), float(0), float(0), float(0)
    
    for _ in range(num):
        A += 1.1
        B += 1.11
        C += 1.111
        D += 1.1111
        E += 1.11111
    
    return A, B, C, D, E
%%timeit
returntuple(10000)

16.2 µs ± 5.84 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

  • ディクショナリ
@jit(nopython=True)
def returndic(num):
    A, B, C, D, E = float(0), float(0), float(0), float(0), float(0)
    
    for _ in range(num):
        A += 1.1
        B += 1.11
        C += 1.111
        D += 1.1111
        E += 1.11111
    
    return {'A':A, 'B':B, 'C':C, 'D':D, 'E':E}
%%timeit
returndic(10000)

42.6 µs ± 23.2 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

タプルの方が2.6倍早くなります。 大規模な配列だともっと差がでるようです。

まとめ

  • 戻り値の型は何でも大丈夫。気にしなくても良い。
  • しかし、numba.jitを使う場合等、速度を重視する場合タプルの方が良い。

  • 例の話はpix2pixでした。