【问题标题】:Understanding run time with numpy arrays?了解 numpy 数组的运行时间?
【发布时间】:2016-07-08 19:21:14
【问题描述】:

我想知道是否有人可以帮助我理解为什么以下两个程序的运行速度明显不同(第一个需要大约 1/10 秒,第二个需要大约 3 秒)。

def gaussian(x, h, m, c):
    return list(h * exp(-(x-m)**2/(2*c**2)))

x = np.linspace(0, 1000, 1001)

for i in range(1000):
    gaussian(x, 50, 500, 10)

def gaussian2(x, h, m, c):
    def computer(x):
        return h * exp(-(x-m)**2/(2*c**2))
    y = []
    for val in x:
        y.append(computer(val))
return y

x = np.linspace(0, 1000, 1001)

for i in range(1000):
    gaussian2(x, 50, 500, 10)

我需要第二个版本的唯一原因是因为它可以让我查看列表中的所有元素,以便我可以对它们执行其他操作(此示例中未说明)。但这不是我要问的——我问的是为什么第二种形式比第一种慢得多。

谢谢!

【问题讨论】:

  • 因为(假设 exp 函数是从 numpy 导入的)第一个函数适用于矢量化数据(向量/数组/列等),而第二个函数适用于标量值。 numpy 中的大多数矢量化操作都是使用 Cython 实现的,并且与它们的标量替代方案相比要快得多...
  • exp np.exp 还是math.exp

标签: python numpy ipython


【解决方案1】:

MaxU 是对的,主要原因是 numpy 中的矢量化数学比 Python 中的标量数学更快。然而,与循环遍历 Python 列表相比,循环遍历 numpy 数组对性能的影响也很重要。在这种情况下,它并没有像数学那样显示出来,但在其他情况下,它可能是主要的减速因素

import numpy as np
import math

def gaussian(x, h, m, c):
    return list(h * np.exp(-(x-m)**2/(2*c**2)))

def gaussian2(x, h, m, c):
    def computer(x):
        return h * math.exp(-(x-m)**2/(2*c**2))
    y = []
    for val in x:
        y.append(computer(val))
    return y

x = np.linspace(0, 1000, 1001)
x_list = x.tolist()

%timeit gaussian(x, 50, 500, 10)
%timeit gaussian2(x, 50, 500, 10)
%timeit gaussian2(x_list, 50, 500, 10)

产量:

10000 loops, best of 3: 114 µs per loop
100 loops, best of 3: 2.97 ms per loop
100 loops, best of 3: 2.35 ms per loop

所以很明显,最大的瓶颈是数学,但与列表相比,循环遍历 numpy 数组会有些慢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多