ホームページ > バックエンド開発 > Python チュートリアル > コードを高速化するための優れた Python パフォーマンス最適化テクニック

コードを高速化するための優れた Python パフォーマンス最適化テクニック

Linda Hamilton
リリース: 2024-12-14 10:53:10
オリジナル
554 人が閲覧しました

owerful Python Performance Optimization Techniques for Faster Code

私は Python 開発者として、高パフォーマンスのアプリケーションを作成するにはコードの最適化が重要であることを学びました。この記事では、実行速度とメモリ効率を向上させる実践的な方法に焦点を当て、Python コードのパフォーマンスを向上させるために私が使用した 7 つの強力なテクニックを紹介します。

ジェネレータとイテレータ

Python コードを最適化する最も効果的な方法の 1 つは、ジェネレーターとイテレーターを使用することです。これらのツールは、すべてを一度にメモリにロードせずにデータを処理できるため、大規模なデータセットを扱う場合に特に役立ちます。

メモリに収まらないほど大きすぎるシーケンスを扱う必要がある場合、私はジェネレーターをよく使用します。素数を生成するジェネレーター関数の例を次に示します。

def prime_generator():
    yield 2
    primes = [2]
    candidate = 3
    while True:
        if all(candidate % prime != 0 for prime in primes):
            primes.append(candidate)
            yield candidate
        candidate += 2
ログイン後にコピー
ログイン後にコピー

このジェネレーターを使用すると、すべての素数をメモリに保存せずに、無限の素数シーケンスを扱うことができます。次のように使用できます:

primes = prime_generator()
for _ in range(10):
    print(next(primes))
ログイン後にコピー
ログイン後にコピー

リスト内包表記とジェネレーター式

リスト内包表記とジェネレータ式は簡潔で、多くの場合、従来のループに代わる高速な代替手段です。これらは、新しいリストの作成やシーケンスの反復処理に特に役立ちます。

偶数を二乗するリスト内包表記の例を次に示します。

numbers = range(10)
squared_evens = [x**2 for x in numbers if x % 2 == 0]
ログイン後にコピー
ログイン後にコピー

大きなシーケンスの場合は、メモリを節約するためにジェネレーター式を使用することを好みます。

numbers = range(1000000)
squared_evens = (x**2 for x in numbers if x % 2 == 0)
ログイン後にコピー
ログイン後にコピー

高性能コンテナのデータ型

Python のコレクション モジュールは、コード効率を大幅に向上させるいくつかの高性能コンテナ データ型を提供します。

リストの両端からの高速な追加とポップが必要な場合は、よく deque (両端キュー) を使用します。

from collections import deque

queue = deque(['a', 'b', 'c'])
queue.append('d')
queue.appendleft('e')
ログイン後にコピー
ログイン後にコピー

Counter は、ハッシュ可能なオブジェクトをカウントするためのもう 1 つの便利なデータ型です。

from collections import Counter

word_counts = Counter(['apple', 'banana', 'apple', 'cherry'])
ログイン後にコピー
ログイン後にコピー

高速検索のためのセットと辞書

セットと辞書は内部でハッシュ テーブルを使用するため、検索やメンバーシップ テストが非常に高速になります。アイテムがコレクション内に存在するかどうかを確認する必要があるとき、またはリストから重複を削除する必要があるときは常にこれらを使用します。

メンバーシップを迅速にテストするためのセットの使用例を次に示します:

numbers = set(range(1000000))
print(500000 in numbers)  # This is much faster than using a list
ログイン後にコピー

Numba によるジャストインタイムコンパイル

数値計算の場合、Numba はジャストインタイム コンパイルを通じて速度を大幅に向上させることができます。以下は、Numba を使用してマンデルブロ集合を計算する関数を高速化する例です。

from numba import jit
import numpy as np

@jit(nopython=True)
def mandelbrot(h, w, maxit=20):
    y, x = np.ogrid[-1.4:1.4:h*1j, -2:0.8:w*1j]
    c = x + y*1j
    z = c
    divtime = maxit + np.zeros(z.shape, dtype=int)

    for i in range(maxit):
        z = z**2 + c
        diverge = z*np.conj(z) > 2**2
        div_now = diverge & (divtime == maxit)
        divtime[div_now] = i
        z[diverge] = 2

    return divtime
ログイン後にコピー

この関数は、純粋な Python の同等の関数よりも最大 100 倍高速です。

C-Speed 用 Cython

さらにスピードが必要なときは、Cython に頼ります。 Cython を使用すると、Python コードを C にコンパイルできるため、パフォーマンスが大幅に向上します。 Cython 関数の簡単な例を次に示します。

def prime_generator():
    yield 2
    primes = [2]
    candidate = 3
    while True:
        if all(candidate % prime != 0 for prime in primes):
            primes.append(candidate)
            yield candidate
        candidate += 2
ログイン後にコピー
ログイン後にコピー

この Cython 関数は、純粋な Python 実装よりも数倍高速です。

プロファイリングと最適化

最適化する前に、ボトルネックがどこにあるのかを特定することが重要です。タイミングには cProfile を、メモリ使用量の分析にはmemory_profilerを使用します。

cProfile の使用方法は次のとおりです:

primes = prime_generator()
for _ in range(10):
    print(next(primes))
ログイン後にコピー
ログイン後にコピー

メモリプロファイリングの場合:

numbers = range(10)
squared_evens = [x**2 for x in numbers if x % 2 == 0]
ログイン後にコピー
ログイン後にコピー

これらのツールは、最も影響が大きい箇所に最適化の取り組みを集中させるのに役立ちます。

functools.lru_cache によるメモ化

メモ化は、高価な関数呼び出しの結果をキャッシュするために私が使用しているテクニックです。 functools.lru_cache デコレータを使用すると、これが簡単になります。

numbers = range(1000000)
squared_evens = (x**2 for x in numbers if x % 2 == 0)
ログイン後にコピー
ログイン後にコピー

これにより、冗長な計算が回避され、再帰関数が大幅に高速化されます。

itertools を使用した効率的な反復

itertools モジュールは、イテレータを作成するための高速でメモリ効率の高いツールのコレクションを提供します。私はこれらをシーケンスの結合や順列の生成などのタスクによく使用します。

itertools.combinations の使用例を次に示します。

from collections import deque

queue = deque(['a', 'b', 'c'])
queue.append('d')
queue.appendleft('e')
ログイン後にコピー
ログイン後にコピー

パフォーマンスの高い Python コードを作成するためのベスト プラクティス

私は長年にわたり、効率的な Python コードを作成するためのいくつかのベスト プラクティスを開発してきました。

  1. ループの最適化: できるだけ多くのコードをループの外に移動するようにしています。ネストされたループの場合、内側のループが可能な限り高速になるようにします。

  2. 関数呼び出しのオーバーヘッドを減らす: 頻繁に呼び出される非常に小さな関数の場合は、インライン関数またはラムダ式の使用を検討します。

  3. 適切なデータ構造を使用する: タスクに適したデータ構造を選択します。たとえば、メンバーシップの高速テストにはセットを使用し、キーと値の高速検索には辞書を使用します。

  4. オブジェクトの作成を最小限に抑える: 新しいオブジェクトの作成は、特にループ内での処理にコストがかかる可能性があります。可能な限りオブジェクトを再利用するようにしています。

  5. 組み込み関数とライブラリを使用する: Python の組み込み関数と標準ライブラリは多くの場合最適化されており、カスタム実装よりも高速です。

  6. グローバル変数を避ける: グローバル変数へのアクセスは、ローカル変数へのアクセスよりも遅くなります。

  7. メンバーシップ テストには 'in' を使用します: リスト、タプル、セットの場合、'in' を使用するとループより高速です。

これらの実践のいくつかを組み込んだ例を次に示します。

from collections import Counter

word_counts = Counter(['apple', 'banana', 'apple', 'cherry'])
ログイン後にコピー
ログイン後にコピー

この関数は、defaultdict を使用してキーが存在するかどうかの明示的なチェックを回避し、単一ループでデータを処理し、最終的な計算には辞書内包表記を使用します。

結論として、Python コードを最適化するには練習と経験が必要なスキルです。これらのテクニックを適用し、最適化の影響を常に測定することで、エレガントなだけでなくパフォーマンスの高い Python コードを作成できます。時期尚早な最適化が諸悪の根源であることを忘れないでください。そのため、最適化が本当に必要な箇所を特定するために、必ず最初にコードのプロファイリングを行ってください。


私たちの作品

私たちの作品をぜひチェックしてください:

インベスターセントラル | 投資家中央スペイン人 | 中央ドイツの投資家 | スマートな暮らし | エポックとエコー | 不可解な謎 | ヒンドゥーヴァ | エリート開発者 | JS スクール


私たちは中程度です

Tech Koala Insights | エポックズ&エコーズワールド | インベスター・セントラル・メディア | 不可解な謎 中 | 科学とエポックミディアム | 現代ヒンドゥーヴァ

以上がコードを高速化するための優れた Python パフォーマンス最適化テクニックの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート