首頁  >  文章  >  後端開發  >  效能追求第二部分:Perl 與 Python

效能追求第二部分:Perl 與 Python

WBOY
WBOY原創
2024-07-31 12:37:22674瀏覽

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

numba 出奇的慢! ?難道是由於 mohawk2 在 IRC 交流中關於此問題指出的編譯開銷造成的嗎?
為了測試這一點,我們應該在執行基準測試之前呼叫一次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
最後,我決定在同一個例子中使用 Base 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 的編譯開銷會產生
  • 錯誤
  • 印象,即它比 Numpy 慢。考慮到編譯開銷時,Numba 比 Numpy 快 2 倍 Joblib 的平行化確實改進了基礎 Python,但仍然不如單執行緒 Perl 實作
  • 多執行緒 PDL(和 OpenMP)碾壓(不是崩潰!)所有語言中的所有其他實作。 希望這個帖子 提供了一些值得思考的東西 用於下一次資料/計算密集型操作的語言。 本系列的下一部分將研究在 C 中使用陣列的相同範例。最後一部分將(希望)提供有關記憶體局部性的影響以及使用動態類型語言所產生的開銷的一些見解。

以上是效能追求第二部分:Perl 與 Python的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn