「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > パフォーマンスの探求パート II : Perl と Python

パフォーマンスの探求パート II : Perl と Python

2024 年 8 月 1 日に公開
ブラウズ:916

The Quest for Performance Part II : Perl vs Python


おもちゃのパフォーマンスの例を実行したので、少し脱線してパフォーマンスを
と比較してみます。 いくつかの Python 実装。まず計算の段階を設定し、コマンドライン
を提供しましょう。 Python スクリプトの機能。

import argparse
import time
import math
import numpy as np
import os
from numba import njit
from joblib import Parallel, delayed

parser = argparse.ArgumentParser()
parser.add_argument("--workers", type=int, default=8)
parser.add_argument("--arraysize", type=int, default=100_000_000)
args = parser.parse_args()
# Set the number of threads to 1 for different libraries
print("=" * 80)
print(
    f"\nStarting the benchmark for {args.arraysize} elements "
    f"using {args.workers} threads/workers\n"
)

# Generate the data structures for the benchmark
array0 = [np.random.rand() for _ in range(args.arraysize)]
array1 = array0.copy()
array2 = array0.copy()
array_in_np = np.array(array1)
array_in_np_copy = array_in_np.copy()

そして、出場者はこちらです:

  • ベースPython
  for i in range(len(array0)):
    array0[i] = math.cos(math.sin(math.sqrt(array0[i])))
  • Numpy (シングルスレッド)
np.sqrt(array_in_np, out=array_in_np)
np.sin(array_in_np, out=array_in_np)
np.cos(array_in_np, out=array_in_np)
  • Joblib (この例は真のインプレース例ではないことに注意してください。ただし、out 引数を使用して実行することはできませんでした)
def compute_inplace_with_joblib(chunk):
    return np.cos(np.sin(np.sqrt(chunk))) #parallel function for joblib

chunks = np.array_split(array1, args.workers)  # Split the array into chunks
numresults = Parallel(n_jobs=args.workers)(
        delayed(compute_inplace_with_joblib)(chunk) for chunk in chunks
    )# Process each chunk in a separate thread
array1 = np.concatenate(numresults)  # Concatenate the results
  • ナンバ
@njit
def compute_inplace_with_numba(array):
    np.sqrt(array,array)
    np.sin(array,array)
    np.cos(array,array)
    ## njit will compile this function to machine code
compute_inplace_with_numba(array_in_np_copy)

タイミング結果は次のとおりです:

In place in (  base Python): 11.42 seconds
In place in (Python Joblib): 4.59 seconds
In place in ( Python Numba): 2.62 seconds
In place in ( Python Numpy): 0.92 seconds

ナンバは意外と遅い!?この問題に関する IRC 交換で mohawk2 が指摘したように、コンパイルのオーバーヘッドが原因でしょうか?
これをテストするには、ベンチマークを実行する前に 1 回 compute_inplace_with_numba を呼び出す必要があります。そうすることで、Numba の方が Numpy よりも高速になっていることがわかります。

In place in (  base Python): 11.89 seconds
In place in (Python Joblib): 4.42 seconds
In place in ( Python Numpy): 0.93 seconds
In place in ( Python Numba): 0.49 seconds

最後に、同じ例でベース R を使用することにしました:

n



次のタイミング結果が得られました:

Time in base R: 1.30 seconds

Perl の結果と比較すると、この例について次のことがわかります:

  • ベース Python のインプレース操作は Perl よりも最大 3.5 遅かった
  • シングルスレッド PDL と numpy ではほぼ同じ結果が得られ、それに近い結果がベース R
  • で続きました。
  • Numba のコンパイル オーバーヘッドを考慮していないため、Numpa よりも遅いという
  • 印象が生まれます。コンパイルのオーバーヘッドを考慮すると、Numba は Numpy より 2 倍高速です
  • Joblib による並列化はベース Python を改善しましたが、シングルスレッドの Perl 実装にはまだ劣っていました
  • マルチスレッド PDL (および OpenMP) は、すべての言語で他のすべての実装をクラッシュしました (クラッシュしませんでした!)。 この投稿があれば幸いです について考える材料を提供します 次のデータ/計算集約型操作に使用する言語。 このシリーズの次のパートでは、C の配列を使用した同じ例を見ていきます。この最終回では、メモリの局所性と動的型付け言語の使用によって発生するオーバーヘッドの影響について (できれば) 洞察が得られるでしょう。
リリースステートメント この記事は次の場所に転載されています: https://dev.to/chrisarg/the-quest-for-performance-part-ii-perl-vs-python-5gdg?1 侵害がある場合は、[email protected] までご連絡ください。それを削除するには
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3