まず、ループの中で math.pi を一度だけ呼び出す処理のベンチマークを計測します。
ベンチマークのソースコードです。
from benchmarker import Benchmarker # グローバル変数と専用クラスは先に定義 g_math = __import__('math') c_math = LazyImport('math') with Benchmarker(1000000, cycle=3, extra=1) as bench: @bench("local") def _(bm): for _ in bm: import math math.pi @bench("global") def _(bm): for _ in bm: global g_math if g_math is None: g_math = __import__('math') g_math.pi @bench("class") def _(bm): for _ in bm: c_math.pi
計測結果です。
## benchmarker: release 4.0.1 (for python) ## python version: 3.4.0 ## python compiler: MSC v.1600 32 bit (Intel) ## python platform: Windows-8-6.2.9200 ... ## Ranking real global 0.5394 (100.0) ******************** local 5.1763 ( 10.4) ** class 5.2870 ( 10.2) **計測結果からは、グローバル変数式が圧倒的に高速となりました。
この計測では、ローカルimport と LazyImportクラスはほぼ等速です。
続けて、ループの中で math.pi を2回呼び出す処理のベンチマークを計測します。
ベンチマークのソースコードです。
from benchmarker import Benchmarker # グローバル変数と専用クラスは先に定義 g_math = __import__('math') c_math = LazyImport('math') with Benchmarker(1000000, cycle=3, extra=1) as bench: @bench("local") def _(bm): for _ in bm: import math math.pi math.pi @bench("global") def _(bm): for _ in bm: global g_math if g_math is None: g_math = __import__('math') g_math.pi g_math.pi @bench("class") def _(bm): for _ in bm: c_math.pi c_math.pi
計測結果です。
## benchmarker: release 4.0.1 (for python) ## python version: 3.4.0 ## python compiler: MSC v.1600 32 bit (Intel) ## python platform: Windows-8-6.2.9200 ... ## Ranking real global 0.7084 (100.0) ******************** local 5.4640 ( 13.0) *** class 10.2182 ( 6.9) *グローバル変数式が相変わらず速いです。
そして、LazyImportクラスは如実に遅くなりました。これは、LazyImportクラスは参照される度に getattr() を呼ぶことが原因です。
結論として、以下の2つが言えます。
- import は2回目以降でもそれなりに重い処理である。よって、import 箇所に繰り返し通る可能性があるなら、グローバル変数式を使うべき。
- LazyImportクラスは動作が遅い。元々高速化のための lazy import であるのに、これではあまり使い道がない。
0 件のコメント:
コメントを投稿