La quête de la performance, partie II : Perl vs Python

WBOY
Libérer: 2024-07-31 12:37:22
original
508 Les gens l'ont consulté

The Quest for Performance Part II : Perl vs Python


Après avoir exécuté un exemple de performance de jouet, nous allons maintenant m'éloigner quelque peu et comparer la performance avec
quelques implémentations Python. Commençons par préparer le terrain pour les calculs et fournissons la ligne de commande
capacités du script 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()
Copier après la connexion

Et voici nos candidats :

  • BasePython
for i in range(len(array0)): array0[i] = math.cos(math.sin(math.sqrt(array0[i])))
Copier après la connexion
  • Numpy (un seul thread)
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)
Copier après la connexion
  • Joblib (notez que cet exemple n'est pas un véritable exemple sur place, mais je n'ai pas pu le faire fonctionner en utilisant les arguments 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
Copier après la connexion
  • 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)
Copier après la connexion

Et voici les résultats du timing :

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
Copier après la connexion

Le numba est étonnamment plus lent !? Cela pourrait-il être dû à la surcharge de compilation, comme l'a souligné mohawk2 dans un échange IRC sur ce problème ?
Pour tester cela, nous devrions appeler computing_inplace_with_numba une foisavantd'exécuter le benchmark. Cela montre que Numba est désormais plus rapide que 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
Copier après la connexion

Finalement, j'ai décidé de prendre la base R pour rouler dans le même exemple :

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))
Copier après la connexion

qui a donné le résultat de timing suivant :

Time in base R: 1.30 seconds
Copier après la connexion

Par rapport aux résultats Perl, nous notons ce qui suit à propos de cet exemple :

  • Les opérations sur place dans Python de base étaient ~ 3,5plus lentesque Perl
  • PDL à thread unique et numpy ont donné des résultats presque identiques, suivis de près par la base R
  • Le fait de ne pas tenir compte de la surcharge de compilation de Numba donne lafausseimpression qu'il est plus lent que Numpy. En tenant compte de la surcharge de compilation, Numba est x2 plus rapide que Numpy
  • La parallélisation avec Joblib s'est améliorée par rapport à Python de base, mais était toujours inférieure à l'implémentation Perl à thread unique
  • Le PDL multithread (et OpenMP) a écrasé (pas planté !) toutes les autres implémentations dans toutes les langues). J'espère que ce post donne matière à réflexion le langage à utiliser pour votre prochaine opération gourmande en données/calcul. La prochaine partie de cette série examinera le même exemple utilisant des tableaux en C. Ce dernier volet fournira (espérons-le) quelques informations sur l'impact de la localité mémoire et la surcharge induite par l'utilisation de langages typés dynamiquement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!