Julia代码优化:向量计算和求和

我在一个 Julia 项目中,我想oneAttempt在下面的代码中优化我的功能。

下面对我的代码进行简要说明:

  • 函数oneAttmept实现了一定的递归算法,返回终端结果。
  • 变量f是通过我algorithm part在下面的代码中编写的算法更新的变量(我会在这个问题中省略这部分)。
  • 函数oneAttempt将在 for 循环下多次调用(超过 1000 次)。
function oneAttempt()
            n = 30
            m = 900

            x = rand(Normal(), n, n)
            A = ones(n, n) * sum(sum(x, dims = 1))
    
            # f would be passed to the algorithm below.
            # f0 is the initial value of f
            f0 = ones(n, n) + x - (1 / m) * A
            f = copy(f0)
            o = zeros(n, n)

            #=
            algorithm part:    
            while loop in which f would be updated many times under complicated algorithm 
            =#
            
            return f;
end

# the function `oneAttempt` would be called many times (more than 1000 times) under for loop.

我想有更好的优化方法f0,因为我听说向量计算将是 Julia 编码中的一个普通瓶颈。

有没有更好的编码方式?

任何信息,将不胜感激。

回答

您的示例不是完全独立的,这使得提出改进建议变得更加困难,因为我不知道可以在不改变其功能的情况下更改哪些部分。但总的来说,我会说你的问题是你正在创建很多不必要的数组,你的第一个策略应该是减少它。

例如:

A = ones(n, n) * sum(sum(x, dims = 1))

这会在内部创建一个向量sum,然后将其求和。此外,不需要ones(n, n)更多的分配,没有任何目的。相反,写

A = sum(x)

这对整个数组求和x,不需要数组。(我怀疑您来自 Matlab,其中sum(x)对矩阵的列求和(除非它是 1xN 矩阵,在这种情况下它对行求和!),但即使在 Matlab 中,您也可以编写sum(x, [], 'all')而不是sum(sum(x)).)

这里:

f0 = ones(n, n) + x - (1 / m) * A

您还应该避免不必要的分配。无需创建数组,只需使用广播即可。我会这样写:

f0 = (1 + A/m) .+ x  # 1 and A/m are both scalar, so don't dot the plus in the parens.

这里

f = copy(f0)
o = zeros(n, n)

你创建更多的数组,一个副本和zeros. 我不知道它们是干什么用的,但我怀疑你不需要它。如果您添加更多上下文,我可以对其发表评论。

但总的来说,减少不必要的数组,改用广播,以及可能的就地操作。

  • TIL about `sum(x, [], 'all'` for MATLAB! (Also great answer IMHO)

以上是Julia代码优化:向量计算和求和的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>