2017-12-02 21 views
4

私はMac(OS X 10.13.1を実行中)にHomebrew-installed Pythonをインストールしています。通訳者が起きるのに慌てて長い時間を要することに気づいた。この問題を解決しようとするアウト設定でPythonインタプリタが起動するまでに12秒かかります。すべてが `import pyexpat`で使われます

は、私はtimeで簡単なチェックをした:12秒:問題のegregiousnessを明らかにした

PIPER-ALPHA:~$ time bpython -c 'pass' 

real 0m12.141s 
user 0m1.662s 
sys  0m10.073s 

...!

それから、gnomon - extremely handy npm moduleを使用して、CLIツールのタイミングを箇条書きすることで問題の原因となっているPythonモジュールを特定しました。私は、このコマンドを使用:

PIPER-ALPHA:~$ PYTHONVERBOSE=1 bpython -c 'pass' 2>&1 | tee -a /tmp/bpython-startup-messages | gnomon 

... gnomon出力は冗長なPythonインタプリタの出力によって発行された各ラインにかかる時間を示しています。それは次のようになります。

verbose Python interpreter startup output timed with gnomon

...私は実行することはほぼ12秒にを取った出力のラインを強調している - これまでで最長のを、一つ一つの他のラインは、典型的には数ナノ秒を要した、またはでとおそらく数μ秒です。

通常、私は気高いPython拡張モジュールに遭遇した場合、自分でそれを再コンパイルしたり、ソースから微調整したりして、必要に応じて適切に問題を解決します。しかし、この場合、私はより大きなPython標準ライブラリモジュールの一部であるc-extensionモジュールを扱っています。これらのモジュールはすべてHomebrewバイナリパッケージ(Homebrew argotの "bottle"と呼ばれています)に同梱されていますこのバージョンのPython

他に誰かが証明できる問題ですか?特に、同様の状況下でPythonを実行しているときに他の誰かが見る問題ですか?そして、最も重要なことは、どうすれば修正できるのでしょうか? Homebrewを使用するか、使用しないでPythonインストール全体を再構築する必要がありますか?

答えて

2

私はこれを理解しました - 答えは同時に照らして恥ずかしいと判明しました - そして、私の解決策は同様の状況に直面したときに他人を助けるかもしれません。

一言:Pythonインタプリタの読み込み中にPython拡張モジュールが大量にインストールされているために、私が経験したように長い間〜12秒がかかりました。 であり、であり、Python 2.7のバンドルxml.parsers.expatモジュールの問題でも、C-API pyexpat拡張でも問題ではありませんでした。

私はこれらのモジュールを指している直接的で直接的な証拠であると思われるものを提供したgnomonツールを使用して、問題のあるコードがどこに見つかったのか私の誤解を招きました。

私の質問を投稿した後、私はちょっとした法医学的な話をしました。コマンドラインの速度チェックを呼び出している間に私がインタプリタに渡していたPythonコードを変更すると、gnomonのレポートは同じ12秒プラスの停止を示しますが、別のimportステートメントの発生率で表示されることがわかりました。さらに、いくつかのコマンドバリエーション(例えば、pythonpy CLTを使用して実行されたもの)は、停止動作によってまったく悩まされないことが分かった。

私は偶然に遭遇したときに、問題の兆候の原因となるコード行を特定できました。テストを実行している間、非常に長い停止はそれほど厄介ではありませんでした。途中での多数のテスト。 KeyboardInterrupt例外で終了したもの中止され、テストの実行、および付随するスタックトレース出力は、物事がドラッグされた機能を明らかにした:

exculpatory stacktrace

...輸入pkg_resourcesモジュールは、、sys.pathで指定された拡張機能の各ディレクトリを歩きますそれぞれの拡張子の各パッケージを列挙し、続いてすべての関連メタデータを読み込んで解析します。 pkg_resources(それ自体が本質的なsetuptoolsモジュールの一部である)のいずれかの部分を使用すると、この時間のかかる動作がトリガされます(少なくとも特定のインタプリタ呼び出しの存続期間中はキャッシュされます)。あなたのPythonインストールの設定方法とインタプリタの呼び出し方法によっては、pkg_resourcesの使用をトリガーする何かをするかもしれないし、そうしないかもしれませんが、Pythonエクステンションパッケージでかなり広く使われています。それは何かによって誘発されるでしょう。

actual function responsible for the actual loop that actually enumerates the packages_initialize_master_working_set()です。これは上のスクリーンショットで強調したものです。これは、すべて私のKeyboardInterruptスタックトレースが明らかにしたものです。そこから、イライラしている停止がチーズショップのパッケージの数の急峻な一次関数であることがすぐに分かった(何か私はラップトップをアップグレードした後に無謀だった)。

私はすぐにインストールしたエクステンションのおよそ50%をピストルアンインストールに進んで、私の積極的に開発したPythonのもののほとんどを孤立したvirtualenvプロジェクトディレクトリに持ち上げて別の40%

ぼんやりとした分析ツールを使って私を巧みに誤解させ、実際のソリューションを偶然見つけたので、私は自分の不注意な不注意に起因する問題に陥りました。それにもかかわらず、それは他のPythonic開発者をそこに噛み込ませる可能性があり、そのために価値があるものです。あなたはここで、私の断固たる冒険から、問題のトリアージと診断を学ぶように招かれます。