>백엔드 개발 >파이썬 튜토리얼 >성능 탐구 2부: Perl과 Python

성능 탐구 2부: 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의 Inplace 작업은 Perl보다 ~ 3.5 느렸습니다
  • 단일 스레드 PDL과 numpy는 거의 동일한 결과를 제공했으며 기본 R이 그 뒤를 바짝 쫓았습니다
  • Numba의 컴파일 오버헤드를 고려하지 못하면 Numpy보다 느리다는 거짓 인상을 받게 됩니다. 컴파일 오버헤드를 고려하면 Numba는 Numpy보다 2배 빠릅니다
  • Joblib를 사용한 병렬화는 기본 Python보다 향상되었지만 여전히 단일 스레드 Perl 구현보다는 열등했습니다
  • 멀티 스레드 PDL(및 OpenMP)은 모든 언어의 다른 모든 구현을 무너뜨렸습니다(충돌하지 않았습니다!). 이번 포스팅은 바랍니다 생각할 거리를 제공합니다 다음 데이터/계산 집약적 작업에 사용할 언어입니다. 이 시리즈의 다음 부분에서는 C의 배열을 사용하는 동일한 예제를 살펴볼 것입니다. 이 마지막 부분에서는 메모리 지역성의 영향과 동적 유형 언어를 사용하여 발생하는 오버헤드에 대한 통찰력을 제공할 것입니다.

위 내용은 성능 탐구 2부: Perl과 Python의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.