首页  >  文章  >  后端开发  >  性能追求第二部分: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