1

pickle/dill/cpickle を使用して、インポートされたモジュールをピクルしてインポート速度を向上させることはできますか? たとえば、Shapely モジュールは、私のシステムでは、必要なすべての依存関係を見つけてロードするのに 5 秒かかります。これは本当に避けたいことです。

インポートを一度ピクルして、毎回遅いインポートを行う代わりに、そのピクルを再利用できますか?

4

3 に答える 3

1

モジュールをdillシリアル化できますが、作業を保存しないモジュールをシリアル化する方法からわかりますimport。モジュールをシリアル化するときdillは、モジュールをインポートする関数を呼び出すだけです。したがって、@ dimo414 が述べているように、答えはノーです。

>>> import dill
>>> import re
>>> _re = dill.dumps(re)
>>> re_ = dill.loads(_re)
>>> re_
<module 're' from '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.pyc'>
>>> _re
'\x80\x02cdill.dill\n_import_module\nq\x00U\x02req\x01\x85q\x02Rq\x03.'
>>> 
于 2016-05-09T13:01:06.850 に答える
1

いいえ。まず第一に、モジュールをピクルすることはできません。エラーが発生します。

>>> import pickle, re
>>> pickle.dump(re, open('/tmp/re.p', 'wb'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'module'>: attribute lookup module on builtins failed

より概念的には、モジュールをシリアライズできたとしても、Python がしなければならない作業の量が増えるだけです。

通常、あなたが言うときimport module、Python は次のことをしなければなりません:

  1. モジュールの場所を見つける (通常はファイル システム上のファイル)
  2. ソース コードをメモリ内のバイト コードに解析する (可能であれば、その解析されたバイト コードを.pycファイル.pycとして保存する) か、存在する場合はメモリに直接ロードします。
  3. モジュールが最初にロードされたときに実行されるはずのコードを実行します

何らかの方法でモジュールをピクルする場合、基本的にステップ 2 を独自の中途半端なソリューションに置き換えることになります。

  1. pickle の場所を見つける (通常はファイル システム上のファイル)
  2. それをアンピクルして Python モジュールに戻します
  3. モジュールが最初にロードされたときに実行されるはずのコードを実行します

unpickle は Python の組み込みバイトコード形式よりも遅いと考えて間違いありません。

さらに言えば、Python ファイルの解析は (非常に) 高価ではなく、ほとんど時間もかかりません。実際の速度低下はステップ 3 で発生しますが、それは変更していません。ピクルス化でステップ 3 をスキップする方法があるかどうかを尋ねるかもしれませんが、モジュールが環境の残りの部分に変更を加えないことを保証する方法がないため、一般的には不可能です。

ここで、特に Shapely モジュールについて特別なことを知っているかもしれません。これにより、「インポート時に Shapely が実行するすべての作業を実行間で安全にキャッシュできる」と言えます。その場合の正しい行動は、そのようなキャッシュ動作をライブラリに提供し、 Python がインポートしているコードではなく、Shapely がロードしているデータをキャッシュすることです。

于 2016-01-22T05:43:34.113 に答える