ホームページ >バックエンド開発 >Python チュートリアル >パフォーマンスの探求パート II : Perl と Python

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

WBOY
WBOYオリジナル
2024-07-31 12:37:22696ブラウズ

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 が指摘したコンパイルのオーバーヘッドが原因でしょうか?
これをテストするには、ベンチマークを実行する前に一度 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<-50000000
x<-runif(n)
start_time <- Sys.time()
result <- cos(sin(sqrt(x)))
end_time <- Sys.time()

# Calculate the time taken
time_taken <- end_time - start_time

# Print the time taken
print(sprintf("Time in base R: %.2f seconds", time_taken))

これにより、次のタイミング結果が得られました:

Time in base R: 1.30 seconds

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

  • ベース Python のインプレース操作は、Perl よりも最大 3.5 遅かった
  • シングルスレッド PDL と numpy ではほぼ同じ結果が得られ、ベース R がそれに続きました
  • Numba のコンパイルのオーバーヘッドを考慮していないため、Numba が Numpy よりも遅いという誤った印象が生まれます。コンパイルのオーバーヘッドを考慮すると、Numba は Numpy より 2 倍高速です
  • Joblib による並列化は、ベースの Python よりは改善されましたが、シングルスレッドの Perl 実装にはまだ劣っていました
  • マルチスレッド PDL (および OpenMP) は、すべての言語で他のすべての実装をクラッシュしました (クラッシュしませんでした)。 この投稿があれば幸いです について考える材料を提供します 次のデータ/計算集約型操作に使用する言語。 このシリーズの次のパートでは、C で配列を使用した同じ例を見ていきます。この最終回では、メモリの局所性と動的型付け言語の使用によって発生するオーバーヘッドの影響について (できれば) 洞察が得られるでしょう。

以上がパフォーマンスの探求パート II : Perl と Pythonの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。