numpy数组,python列表和Fortran

很长时间以来,我一直在使用Fortran进行与计算物理有关的工作,最近开始学习和使用Python。我知道以下事实:作为主要用于CPU密集型计算工作的Python,其解释语言通常比Fortran慢。但是后来我认为使用numpy可以显着提高排序等简单任务的性能。

因此,我的测试用例是使用冒泡排序对一个数组/包含随机浮点数的大小为10,000的列表进行排序(只是一个具有许多数组操作的测试用例,因此无需评论算法本身的性能)。我的计时结果如下(所有函数使用相同的算法):

Python3(使用numpy数组,但使用我自己的函数代替numpy.sort):33.115s
Python3(使用列表):9.927s
Fortran(gfortran):0.291秒

Python3(使用numpy.sort):0.269秒(不公平的比较,因为它使用了不同的算法)

令我惊讶的是,使用numpy数组进行操作的速度比使用python list慢约3倍,比使用Fortran慢约100倍。因此,我的问题是:

  1. 在此测试用例中,为什么使用numpy数组运行比python列表慢得多?
  2. 如果我需要的算法尚未在scipy / numpy中实现,并且我需要在Python框架内编写自己的函数,并且考虑到最佳性能,那么我应该使用哪种数据类型:numpy数组或列表?
  3. 如果我的应用程序以性能为导向,并且我想编写与内置numpy函数(例如np.sort)具有相同性能的函数,那么我应该学习/使用哪些工具/框架?
xiekaixu 回答:numpy数组,python列表和Fortran

您似乎误解了NumPy为加快计算速度所做的事情。

使用一些智能的数据保存方式,NumPy的加速并非来自NumPy。或将您的Python代码自动编译为C。

相反,NumPy在C或Fortran中实现了许多有用的算法,numpy.sort()是其中之一。这些函数将np.ndarray理解为输入,并在C / Fortran循环中遍历数据。

如果您想编写快速的NumPy代码,实际上有三种方法可以做到:

  • 将代码分解为NumPy运算(乘法,点积,排序,广播等)
  • 编写要在C / Fortran中实现的算法,并向接受np.ndarray(在内部是您选择的类型的连续数组)的Python编写绑定。
  • 使用Numba通过让Python及时将您的代码编译为机器代码(有一些限制)来加速您的功能
,
  
      
  1. 在此测试用例中,为什么使用numpy数组运行比python列表慢得多?
  2.   

NumPy数组是数字数据的容器。它们包含元数据(数组的类型和形状)和数据本身的内存块。这样,对NumPy数组的元素进行的任何操作都会涉及一些开销。 Python列表针对“普通Python”代码进行了更好的优化:读取和写入列表元素比NumPy数组要快。 NumPy数组的好处来自“整个数组操作”(所谓的数组操作)和编译后的扩展。 C / C ++ / Fortran,Cython或Numba可以访问NumPy数组的内容,而不会产生开销。

  
      
  1. 如果我需要的算法尚未在scipy / numpy中实现,并且需要在Python中编写自己的函数   考虑到最佳性能的框架,我应该使用哪种数据类型   使用:numpy数组还是列表?
  2.   

对于数字代码,NumPy数组更好:您可以在已编译的扩展名中访问其内容“àla C”或“àla Fortran”。

  
      
  1. 如果我的应用程序面向性能,并且我想编写与内置numpy函数具有同等性能的函数   (例如np.sort),我应该学习/使用哪些工具/框架?
  2.   

有很多。您可以使用NumPy C-API用C语言编写(很复杂,我不建议这样做,但是很高兴知道它存在)。 Cython是一种成熟的“类Python”和“类C”语言,可以轻松,逐步地提高性能。 Numba是一个“及时”解释器:如果您限制代码以直接对NumPy数组进行数值运算,则Numba会即时将代码转换为已编译的等效代码。

本文链接:https://www.f2er.com/3082845.html

大家都在问