【问题标题】:How to speed up this python code (conditional in loop)?如何加速这个python代码(循环条件)?
【发布时间】:2014-01-30 22:46:45
【问题描述】:

我试图找到一种在循环中不使用 if...else 条件的方法,以便加快代码速度,知道吗?

for i in range(n):
    for j in range(n):
        if a1[i, j] == 0:
            b1[i, j] = 1
        else:
            b1[i, j] = a1 / np.sin(a1)
        if a2[i, j] == 0:
            b2[i, j] = 1
        else:
            b2[i, j] = a2 / np.sin(a2)

【问题讨论】:

  • 我认为 if/else 语句不是问题所在。您在 for 循环中有一个 for 循环,我猜这更可能是问题的根源。
  • 处理嵌套列表可能会很慢,只是说。
  • 逻辑中可能有一些帮助,但是有两个for 循环,无论如何你都会被O(n^2) 卡住。
  • 我不遵循此代码。看起来a1 是一个数组,因为您使用a1[i,j] 对其进行索引,但您随后设置了b1[i,j] = a1/np.sin(a1)。像往常一样,我是否遗漏了一些明显的东西?
  • @DSM: like is np 指的是 numpy?

标签: python performance loops numpy


【解决方案1】:

您正在计算sinc 函数的倒数。所以你可以这样做:

b1 = 1.0 / np.sinc(a1/np.pi)
b2 = 1.0 / np.sinc(a2/np.pi)

numpy sinc 函数是矢量化的,所以你不需要编写循环。

【讨论】:

  • 感谢您的评论,这绝对是我需要的!
【解决方案2】:

if() 语句被认为是O(1) 时间操作,尽管如果效率至关重要(在这种情况下,在 Python 代码中运行 for 循环不是最佳选择),那么错过的分支预测可能代价高昂。

除了可能错过的分支预测之外,渐近时间是@Keeler 提到的O(n^2)。不过,优化 for 循环内的代码可能有助于解决 Big-Oh 表示法中的一些常数因素,这在实践中非常有成效。

您可以做的优化是遵循@Warren 的建议并使用sinc()

【讨论】:

  • Python 不分支预测。
  • 不,可能不是。为什么不把它留给在硬件中实现分支预测的 CPU 呢?
  • @Keeler:它将在解释字节码的 Python 评估循环中执行此操作。分支预测不会帮助或阻碍字节码中的分支,因为 CPU 看不到这些。
  • 这里不重要;通过使用向量化的 numpy 函数,您可以将数组索引上的循环移动到 C 代码中。
  • @Keeler:Python VM 没有做太多优化,在处理一个 CPython 操作码时,将执行数百个 CPU 操作码,中间有数十个分支,从中获得任何好处该单分支预测非常接近于零。
猜你喜欢
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多