【发布时间】:2019-02-18 01:45:58
【问题描述】:
几天来,我一直在苦苦思考如何优化(不仅让它看起来更漂亮)3 个 嵌套循环,其中包含一个 条件 和一个函数调用。我现在拥有的是以下内容:
def build_prolongation_operator(p,qs):
'''
p: dimension of the coarse basis
q: dimension of the fine basis
The prolongation operator describes the relationship between
the coarse and fine bases:
V_coarse = np.dot(V_fine, I)
'''
q = sum(qs)
I = np.zeros([q, p])
for i in range(0, q):
for j in range(0, p):
for k in range(0, qs[j]):
# if BV i is a child of j, we set I[i, j] = 1
if i == f_map(j, k, qs):
I[i, j] = 1
break
return I
f_map 在哪里:
def f_map(i, j, q):
'''
Mapping which returns the index k of the fine basis vector which
corresponds to the jth child of the ith coarse basis vector.
'''
if j < 0 or j > q[i]:
print('ERROR in f_map')
return None
result = j
for k in range(0, i):
result += q[k]
return result
在分析我的整个代码时,我发现 build_prolongation_operator 被调用了 45 次,f_map 大约 850 万次!!
图片如下:
我曾尝试对列表理解和地图做同样的事情,但没有任何运气。
这是build_prolongation_operator 期望的输入示例:
p = 10
qs = randint(3, size=p)
【问题讨论】:
-
列表推导式或
map将仍然执行您的操作 850 万次。这些构造之间的性能差异对于任何重要的代码(例如您的代码)都可以忽略不计。如果您提供更多上下文(例如qs是什么),则可能设计出更好的算法。还可以考虑研究 numpy 的内置矢量化功能,或者可能是 Cython 以进行蛮力优化。 -
您也许可以用向量乘法替换三个循环。
p、qs是什么,你认为I是什么? -
我认为您的循环之一根本没有必要。特别是外层。请提供 sample 输入,以便我们可以play。
-
@Mad,这将比我建议的记忆更好:-)
-
@MisterMiyagi 谢谢你的时间。为了测试这一点,我将 {qs = np.random.randint(3, size(p))} 设为 p 只是一个整数。
标签: python python-3.x list numpy optimization