简体   繁体   English

np.einsum的速度差

[英]Speed difference in np.einsum

I noticed that np.einsum is faster when it reduces one dimension 我注意到np.einsum一维时速度更快

import numpy as np
a = np.random.random((100,100,100))
b = np.random.random((100,100,100))

%timeit np.einsum('ijk,ijk->ijk',a,b)
# 100 loops, best of 3: 3.83 ms per loop
%timeit np.einsum('ijk,ijk->ij',a,b)
# 1000 loops, best of 3: 937 µs per loop
%timeit np.einsum('ijk,ijk->i',a,b)
# 1000 loops, best of 3: 921 µs per loop
%timeit np.einsum('ijk,ijk->',a,b)
# 1000 loops, best of 3: 928 µs per loop

Which seems very weird to me, as I would expect it to first generate the new array and then sum over it, which is obviously not happening. 这对我来说似乎很奇怪,因为我希望它首先生成新数组,然后对其求和,但这显然没有发生。 What is going on there? 那里发生了什么事? Why is it getting faster, when one drops one dimnesion, but does not get faster after other dimension drops? 为什么当一个维降一个维数时却变得更快,而在其他维降维后却不那么快呢?

Side note: I first thought that it has to do with creating a large array, when it has many dimensions, which I don't think is the case: 旁注:我首先认为这与创建大型数组有关(当数组具有多个维度时),我认为情况并非如此:

 %timeit np.ones(a.shape)
 # 1000 loops, best of 3: 1.79 ms per loop
 %timeit np.empty(a.shape)
 # 100000 loops, best of 3: 3.05 µs per loop

As creating new arrays is way faster. 由于创建新数组的速度更快。

einsum is implemented in compiled code, numpy/numpy/core/src/multiarray/einsum.c.src . einsum在已编译的代码numpy/numpy/core/src/multiarray/einsum.c.src

The core operation is to iterate over all dimensions (eg in your case 100*100*100 times) using the c version of nditer , applying the sum-of-products calculation defined by the ijk string. 核心操作是使用c版本的nditer迭代所有维度(例如,在您的情况下为100*100*100次),应用ijk字符串定义的sum-of-products计算。

But it does various optimizations, including generating views if no multiplication is required. 但是它会进行各种优化,包括在不需要乘法的情况下生成视图。 So it will require careful study to see what's different in your cases. 因此,需要仔细研究以了解您的情况有何不同。

The time divide is between producing a 3d output without summations, and one that sums on one or more axis. 时间间隔介于产生不求和的3d输出和在一个或多个轴上求和的3d输出之间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM