好吧,伙计们,我有个答案:纽比的vectorize。在

不过,请阅读编辑过的部分。您将发现python实际上为您优化了代码,这实际上违背了在本例中使用numpy数组的目的。(但使用numpy数组不会降低性能。)

最后一个测试真正表明python列表是尽可能有效的,因此这个向量化过程是不必要的。这就是为什么我没有把这个问题标为“最佳答案”。在

设置代码:def factory(i): return lambda num: num==i

array1 = list()

for i in range(10000): array1.append(factory(i))

array1 = np.array(array1)

array2 = np.array(xrange(10000))

“无部门”版本:

^{pr2}$

矢量化版本def evaluate2(func, b): return func(b)

vec_evaluate = np.vectorize(evaluate2)

vec_evaluate(array1, array2)

# 100 loops, best of 3: 2.65 ms per loop

编辑

好的,我只想粘贴更多的基准测试,我收到使用以上测试,除了不同的测试用例。在

我做了第三次编辑,展示了如果只使用python列表会发生什么。长话短说,你其实不会后悔太多。这个测试用例在最底层。在

只涉及整数的测试用例

总而言之,如果n很小,那么无扇区的版本更好。否则,矢量化是正确的选择。在

带n = 30%timeit evaluate(array1, array2)

# 10000 loops, best of 3: 35.7 µs per loop

%timeit vec_evaluate(array1, array2)

# 10000 loops, best of 3: 27.6 µs per loop

带n = 7%timeit evaluate(array1, array2)

100000 loops, best of 3: 9.93 µs per loop

%timeit vec_evaluate(array1, array2)

10000 loops, best of 3: 21.6 µs per loop

涉及字符串的测试用例

矢量化获胜。在

设置代码:def factory(i): return lambda num: str(num)==str(i)

array1 = list()

for i in range(7):

array1.append(factory(i))

array1 = np.array(array1)

array2 = np.array(xrange(7))

与n = 10000%timeit evaluate(array1, array2)

10 loops, best of 3: 36.7 ms per loop

%timeit vec_evaluate(array1, array2)

100 loops, best of 3: 6.57 ms per loop

带n = 7%timeit evaluate(array1, array2)

10000 loops, best of 3: 28.3 µs per loop

%timeit vec_evaluate(array1, array2)

10000 loops, best of 3: 27.5 µs per loop

随机测试

只是想看看分支预测是如何发挥作用的。据我所见,其实没什么变化。矢量化通常仍然是成功的。在

设置代码。在def factory(i):

if random() < 0.5:

return lambda num: str(num) == str(i)

return lambda num: num == i

当n = 10000%timeit evaluate(array1, array2)

10 loops, best of 3: 25.7 ms per loop

%timeit vec_evaluate(array1, array2)

100 loops, best of 3: 4.67 ms per loop

当n = 7%timeit evaluate(array1, array2)

10000 loops, best of 3: 23.1 µs per loop

%timeit vec_evaluate(array1, array2)

10000 loops, best of 3: 23.1 µs per loop

使用python列表而不是numpy数组

我运行这个测试来看看当我选择不使用“优化的”numpy数组时发生了什么,我得到了一些非常令人惊讶的结果。在

设置代码几乎相同,只是我选择不使用numpy数组。我也在做这个测试,只针对“随机”的情况。在def factory(i):

if random() < 0.5:

return lambda num: str(num) == str(i)

return lambda num: num == i

array1 = list()

for i in range(10000): array1.append(factory(i))

array2 = range(10000)

以及“无部门”的版本:%timeit evaluate(array1, array2)

100 loops, best of 3: 4.93 ms per loop

您可以看到这实际上是相当令人惊讶的,因为这几乎是我在随机测试用例中收到的关于向量化evaluate的基准测试。在%timeit vec_evaluate(array1, array2)

10 loops, best of 3: 19.8 ms per loop

同样,如果您在使用vec_evaluate之前将这些数组更改为numpy数组,您将获得相同的4.5ms基准测试。在