Rumah >pembangunan bahagian belakang >Tutorial Python >Pencarian untuk Prestasi Bahagian II : Perl vs Python

Pencarian untuk Prestasi Bahagian II : Perl vs Python

WBOY
WBOYasal
2024-07-31 12:37:22700semak imbas

The Quest for Performance Part II : Perl vs Python


Setelah menjalankan contoh persembahan mainan, kami kini akan menyimpang sedikit dan membezakan persembahan dengan
beberapa pelaksanaan Python. Mula-mula mari kita sediakan pentas untuk pengiraan, dan sediakan baris perintah
keupayaan kepada skrip 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()

Dan inilah peserta kami:

  • Sawa Asas
  for i in range(len(array0)):
    array0[i] = math.cos(math.sin(math.sqrt(array0[i])))
  • Numpy (Berbenang tunggal)
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 (perhatikan bahawa contoh ini bukan contoh di tempat yang benar, tetapi saya tidak dapat menjalankannya menggunakan argumen keluar)
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
  • Numba
@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)

Dan berikut ialah keputusan masa:

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 menghairankan lebih perlahan!? Mungkinkah ia disebabkan oleh kompilasi yang berlebihan seperti yang ditunjukkan oleh mohawk2 dalam pertukaran IRC tentang isu ini?
Untuk menguji ini, kita harus memanggil compute_inplace_with_numba sekali sebelum kita melaksanakan penanda aras. Dengan berbuat demikian, menunjukkan bahawa Numba kini lebih pantas daripada 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

Akhirnya, saya memutuskan untuk mengambil pangkalan R untuk tunggangan dalam contoh yang sama:

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))

yang menghasilkan keputusan pemasaan berikut:

Time in base R: 1.30 seconds

Berbanding dengan hasil Perl, kami perhatikan perkara berikut tentang contoh ini:

  • Operasi inplace dalam Python asas adalah ~ 3.5 lebih perlahan daripada Perl
  • PDL berulir tunggal dan numpy memberikan hasil yang hampir sama, diikuti rapat oleh asas R
  • Kegagalan untuk mengambil kira overhed kompilasi Numba menghasilkan tanggapan palsu bahawa ia lebih perlahan daripada Numpy. Apabila mengambil kira overhed kompilasi, Numba adalah x2 lebih pantas daripada Numpy
  • Pejajaran dengan Joblib memang bertambah baik pada Python asas, tetapi masih lebih rendah daripada pelaksanaan Perl utas tunggal
  • PDL berbilang benang (dan OpenMP) dihancurkan (tidak ranap!) setiap pelaksanaan lain dalam semua bahasa). Semoga post ini menyediakan sedikit makanan untuk difikirkan bahasa untuk digunakan untuk operasi intensif data/pengiraan anda yang seterusnya. Bahagian seterusnya dalam siri ini akan melihat contoh yang sama menggunakan tatasusunan dalam C. Ansuran terakhir ini (semoga) memberikan beberapa cerapan tentang kesan lokaliti memori dan overhed yang ditanggung dengan menggunakan bahasa yang ditaip secara dinamik.

Atas ialah kandungan terperinci Pencarian untuk Prestasi Bahagian II : Perl vs Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn