在python中优化部分代码时,我观察到以下内容:
x = np.random.randn(100, 20)
a = np.arange(20)
%timeit x
23 纳秒
%timeit x[a]
1.7微秒
虽然 x[a] 是一个较小的数组,但它需要更多时间才能达到。你知道是什么原因造成的吗?如果我要求 x.T.dot(x( 和 x[a] 而不是 x,则观察到类似的结果。T.dot(x[a](.
虽然你的标题测试用例是有缺陷的,x
只是一个参考,但你的观察如果不是那么极端的
>>> timeit(lambda: x[a], number=1000000)
1.8212362979538739
>>> timeit(lambda: x.copy(), number=1000000)
1.2187692462466657
我们在这里看到的是高级索引的成本。"传统"切片索引的成本要低得多,但仍有开销:
>>> np.all(x[:20] == x[a])
True
>>> timeit(lambda: x[:20].copy(), number=1000000)
0.7956113098189235
%timeit x
次对x
不执行任何操作所需的时间。什么都不做很容易。
%timeit x[a]
倍实际用x
做一件事所需的时间,该事情动态计算出索引操作的含义,然后将 20 个指定的行复制到一个新数组中。做事比什么都不做要难得多。