编辑添加:我认为numba基准不公平,以下注意事项
我正在尝试对以下用例进行数值处理数据的不同方法的基准测试:
问题:根据此用例,以下基准是否合适?如果不合适,如何改进它们?
# importing pandas, numpy, Series, DataFrame in standard way from numba import jit nobs = 10000 nlines = 100 def proc_df(): df = DataFrame({ 'x': np.random.randn(nobs), 'y': np.random.randn(nobs) }) for i in range(nlines): df['z'] = df.x + df.y return df.z def proc_ser(): x = Series(np.random.randn(nobs)) y = Series(np.random.randn(nobs)) for i in range(nlines): z = x + y return z def proc_arr(): x = np.random.randn(nobs) y = np.random.randn(nobs) for i in range(nlines): z = x + y return z @jit def proc_numba(): xx = np.random.randn(nobs) yy = np.random.randn(nobs) zz = np.zeros(nobs) for j in range(nobs): x, y = xx[j], yy[j] for i in range(nlines): z = x + y zz[j] = z return zz
结果(Win 7,具有3年历史的Xeon工作站(四核)。标准和近期的Anaconda分布非常接近。)
In [1251]: %timeit proc_df() 10 loops, best of 3: 46.6 ms per loop In [1252]: %timeit proc_ser() 100 loops, best of 3: 15.8 ms per loop In [1253]: %timeit proc_arr() 100 loops, best of 3: 2.02 ms per loop In [1254]: %timeit proc_numba() 1000 loops, best of 3: 1.04 ms per loop # may not be valid result (see note below)
编辑以将df / series / array传递到函数中而不是在函数内部创建它们(例如,将包含“ randn”的代码行从内部函数移至外部函数)以添加(响应jeff)替代结果:
10 loops, best of 3: 45.1 ms per loop 100 loops, best of 3: 15.1 ms per loop 1000 loops, best of 3: 1.07 ms per loop 100000 loops, best of 3: 17.9 µs per loop # may not be valid result (see note below)
关于numba结果的注释:我认为numba编译器必须在for循环上进行优化,并将for循环减少为单个迭代。我不知道,但这是我能提出的唯一解释,因为它不能比numpy快50倍,对吗?后续问题在这里: 为什么numba比numpy快?
好吧,您实际上不是在这里安排相同的时间(或者,您正在安排不同的方面)。
例如
In [6]: x = Series(np.random.randn(nobs)) In [7]: y = Series(np.random.randn(nobs)) In [8]: %timeit x + y 10000 loops, best of 3: 131 µs per loop In [9]: %timeit Series(np.random.randn(nobs)) + Series(np.random.randn(nobs)) 1000 loops, best of 3: 1.33 ms per loop
因此,[8]乘以实际运算,而[9]包括序列创建(和随机数生成)的开销加上实际运算
另一个例子是proc_serVS proc_df。这proc_df包括在DataFrame中分配特定列的开销(这对于初始创建和后续重新分配实际上是不同的)。
因此,创建结构(您也可以为其计时,但这是一个单独的问题)。执行完全相同的操作并计时。
此外,您说不需要对齐。pandas默认为您提供此功能(没有简单的方法将其关闭,尽管仅需简单检查它们是否已对齐)。在numba中时,您需要“手动”对齐它们。