Zen of Python を読んで、これを Python パーサーにインポートしてください。熱心な Python 初心者は、「解析」という言葉に気づき、「Python は遅いに違いない!」と考えるかもしれません。
ヒント Python は間違いありません。 Python の支持者でさえ、Python はこれらの分野には適していないと言うでしょう。しかし、YouTube は効率的なコードを書くだけで Python を使用しています。必要に応じて、外部実装 (C/C++) コードを使用します。より優れた Python 開発者になるためのヒントをいくつか紹介します:
1. 組み込み関数を使用する: Python で効率的なコードを書くことはできますが、それを上回るのは困難です。組み込み関数は非常に高速です。 2. join() を使用して文字列を連結できます。ただし、Python では文字列は不変であるため、それぞれの「+」操作によって新しい関数が作成されます。一般的な使用法は、Python の配列モジュールを使用して個々の文字を変更することです。完了したら、join() 関数を使用して最終的な文字列を作成します
>>> #これは、多数の文字列を結合するのに適しています。文字列の
>>> for chunk in input():
>>> my_string.join(chunk)
3. Python の複数代入を使用して変数を交換します
これは Python で行われます。 エレガントで高速です: >>> x , y = y, x
これは非常に遅いです:
>>> temp = x
アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト アウト'' ‐ ‐‐‐‐‐ ‐ ‐ _ . ローカル変数を使用してみてください
Python は、グローバル変数を取得するよりも速くローカル変数を取得します。つまり、「global」キーワードを使用しないでください。
5.
"in" キーワードを使用します。シンプルで高速です。
>>> キーを順番に表示します:
>>> "found" を出力します
6. 遅延読み込みを使用して高速化します
「import」宣言を移動します。つまり、特定のモジュールをすぐに使用する必要がなく、後で大量のモジュールをインポートする必要はありません。この手法は、プログラムの起動を高速化するためのものではありませんが、モジュールの読み込み時間をより均等に分散するのに役立ちます
場合によっては、無限ループが必要になります。プログラム内のループ (リスニング ソケットのインスタンスなど)。「while true」でも同じことを実現できますが、「while 1」は 1 ステップの操作です。このトリックにより、Python のパフォーマンスが向上します。 >>> while 1:
>>> #何かをする、while 1
>>> while True:
>>> # 何かをする、wile True
8 を使う。 Python 2.0 以降、リスト内包表記を使用すると、多くの "for" ブロックと "while" ブロックを置き換えることができ、通常はリスト内包表記を使用する方が高速であり、ループ内で予測可能なパターンを見つけるために Python パーサーが最適化されるという利点もあります。より読みやすく (関数型プログラミング)、ほとんどの場合、追加のカウント変数が保存されます。たとえば、1 から 10 までの偶数を数えてみましょう:
>>> # 範囲を反復する良い方法
>>> Evens = [ i for i in range(10) if i%2 == 0]
>>> [0, 2, 4, 6, 8]
>>> # 以下はそれほど Pythonic ではありません
>>> i = 0
>>> Evens = []
> >> while i
>>> if i %2 == 0: Evens.append(i)
>>> i += 1
>>> [0, 2, 4, 6, 8 ]
9. xrange() を使用して長いシーケンスを処理します。
xrange() はシーケンス内の呼び出しごとに 1 つの整数要素しか生成しないため、システム メモリを大幅に節約できます。対照的に、 range() は要素の完全なリストを直接提供するため、ループに使用すると不要なオーバーヘッドが発生します。
10. Python ジェネレーターを使用します:
これにより、メモリが節約され、パフォーマンスが向上します。たとえば、ビデオ ストリームの場合、ストリーム全体ではなく、バイト単位で送信できます。たとえば、
>>> チャンク = ( 1000 * i for i in xrange(1000)) >>> チャンク。 0
>>> chunk.next()
2000
11. itertools モジュールを理解します:
このモジュールは反復と組み合わせに非常に効果的です。たった 3 行の Python コードで、リスト [1, 2, 3] のすべての順列を生成しましょう:
>>> import itertools
>>> iter = itertools.permutations([1,2,3])
>>> list(iter)
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2) 、(3, 2, 1)]
12. リストを並べ替えるための bisect モジュールを学習します:
これは無料の二分探索実装であり、順序付けされたシーケンスをすばやく挿入するためのツールです。つまり、以下を使用できます:
>>> import bisect
>>> bisect.insort(list, element)
リストに要素を挿入したため、sort() を再度呼び出す必要はありません。コンテナの並べ替え。これは長いシーケンスでは非常に負荷がかかる可能性があるためです。
Python のリストは実際には配列であることを理解してください。コンピュータサイエンスで実現しました。 Python のリストは配列です。つまり、最初から検索しなくても、定数時間 O(1) でリストの要素を取得できます。ポイントは何ですか? Python 開発者は、リスト オブジェクトの insert() を使用するときはよく考える必要があります。例: >>> list.insert(0, item)
リストの先頭に要素を挿入するのは効率的ではありません。 list は変更する必要がありますが、挿入の間や挿入のタイミングを早くしたい場合は、list.append() を使用してリストの最後に要素を効果的に追加できます。 Python の deque は二重リンク リストとして実装されるため、高速です。これ以上言わない。
14. dict と set を使用してメンバーをテストする: 要素が辞書またはセットに存在するかどうかを確認します。これは Python では非常に高速です。これは、dict と set がハッシュ テーブルを使用して実装されているためです。検索効率は O(1) に達する可能性があります。したがって、メンバーを頻繁にチェックする必要がある場合は、set または dict をコンテナとして使用してください
>>> mylist = ['a', 'b', 'c'] #より遅い、list:
でメンバーシップをチェックします。 > mylist の 'c'
>>> True
>>> myset = set(['a', 'b', 'c']) # より速く、set:
でメンバーシップを確認 >>> ' c ' in myset:
>>> True
15. Schwartzian Transform を使用した Sort():
ネイティブの list.sort() 関数は非常に高速です。 Python はリストを自然な順序で並べ替えます。場合によっては、不自然な順序で並べ替える必要があることがあります。たとえば、サーバーの場所に基づいて IP アドレスを並べ替えるとします。 Python はカスタム比較をサポートしており、list.sort(CMP()) を使用できますが、関数呼び出しのオーバーヘッドが追加されるため、list.sort() よりも遅くなります。パフォーマンスが問題になる場合は、シュワルツ変換に基づいたグットマン・ロスラー変換を適用できます。これは、使用される実際のアルゴリズムのみに関心があり、その簡単な動作原理は、リストを変換して Python の組み込み関数を呼び出すことができるということです。 list.sort() 内 -> list.sort(CMP()) を使用しない方が高速 -> 低速。
16. Python デコレーターのキャッシュ結果:
「@」記号は Python の装飾構文です。これはトレース、ロック、ログ記録だけを目的としたものではありません。 Python 関数を装飾して、呼び出しの結果を後で使用できるように記憶することができます。この手法はメモ化と呼ばれます。以下に例を示します。
>>> from functools import Wraps
>>> def memo(f):
>>> cache = { }
>>> @wraps(f)
>>> def Wrap(*arg):
>>> 引数がキャッシュにない場合:cache['arg'] = f(*arg)
>>> return cache['arg']
>>> return Wrap
フィボナッチ関数のデコレーターも使用できます:
>>> @memo
>>> def fib(i):
>>> if i
>>> return fib(i- 1) + fib(i-2)
ここでの重要なアイデアは、関数 (装飾) 関数を強化して、計算された各フィボナッチ値を記憶する (キャッシュ内にある場合は計算する必要がない) ことです。
17. Python の GIL (グローバル インタプリタ ロック) を理解する: CPython のメモリ管理はスレッドセーフではないため、
GIL が必要です。単純に複数のスレッドを作成して、マルチコア マシン上で Python がより高速に実行されることを期待することはできません。これは、GIL により、複数のネイティブ スレッドが Python バイトコードを同時に実行することが防止されるためです。言い換えれば、GIL はすべてのスレッドをシリアル化します。ただし、スレッドを使用して生成された複数のプロセスを管理し、Python コードとは独立して実行されるプログラムを高速化することができます。
18. ドキュメントを読むのと同じくらい Python ソース コードにも精通してください:
一部の Python モジュールはパフォーマンスのために C で実装されています。パフォーマンスが重要であり、公式ドキュメントが不十分な場合は、ソース コードを自由に探索してください。基礎となるデータ構造とアルゴリズムを見つけることができます。 Python のソース コード ライブラリは素晴らしい場所です: http://svn.python.org/view/python/trunk/Modules
結論:
これらは、頭で考えることに代わるものではありません。この記事で紹介する Python の提案は、すぐにゴミにまとめられないようにするために、詳細を調べて完全に理解する必要があります。十分な速度ではありません。Python では、外部の力を利用する: 外部コードの分析と実行が必要になります