【问题标题】:Are calculations involving a large matrix using arrays in VBA faster than doing the same calculation manually in Excel?在 VBA 中使用数组进行涉及大型矩阵的计算是否比在 Excel 中手动执行相同的计算更快?
【发布时间】:2018-01-26 11:07:11
【问题描述】:

我正在尝试在 Excel 中将计算作为回归模型的一部分。

我需要计算((X^T)WX)^(-1)(X^T)WY。其中XWY是矩阵,^T^-1表示矩阵转置和求逆运算。

现在,当XWY 尺寸较小时,我只需运行我的宏,它会非常非常快速地计算这些值。

但有时我在处理这种情况时说,XWY 的尺寸分别为5000 X 55000 X 15000 X 1,那么宏可能需要更长的时间运行。

我有两个问题:

  1. 将,而不是使用我的宏在 Excel 工作表上生成矩阵,然后使用 Excel 公式(如 MMULTMINVERSE 等)来计算输出,如果我使用更大维度的矩阵,它会更快VBA 中的数组来做所有的计算? (我不太清楚数组在 VBA 中是如何工作的,所以我实际上不知道它是否会做得更好,因此它是否会更快/计算量更少。)

  2. 如果上述问题的答案是否定的,那就不会更快了。那么有人知道如何加快这样的计算吗?还是我只需要忍受它并等待。

感谢您的宝贵时间。

【问题讨论】:

  • 如果您必须处理大量矩阵,那么 Matlab 可能值得一看。它非常强大,具有巨大的矩阵。对于您的用例,它可能有点过分(我无法确定,因为我不知道您的确切用例)。
  • 我不知道如何解释它,除了我是怎么做的。对不起。
  • 我的意思是您决定哪种工具适合您的情况。 Matlab 是一个非常强大的工具,但不如 Excel 好用。如果 Excel 需要一天或更长时间来计算,我只会切换。
  • 这通常需要几分钟,所以在我看来还不错,不值得使用 matlab。我正在考虑使用 VBA,但我不确定它是否值得。也就是说,如果在 excel 中需要 5 分钟,在 VBA 中需要 4 分钟,那么这是不值得的。但是,如果在 excel 中需要 5 分钟,在 VBA 中需要 30 秒,那么我会尝试做 VBA,你能用你的最佳猜测评论相应的时间范围吗?
  • 这在很大程度上取决于您的源数据的外观。您无法猜测使用 VBA 会获得多大的时间收益。您可以在 VBA 中对该解决方案进行编码并测量获得差异的时间。它还取决于您的 VBA 代码。如果它好它会更快,如果它坏它可能会比 Excel 更慢。您会看到:变量太多,无法准确猜测。

标签: vba excel matrix


【解决方案1】:

考虑到代码的算法相同,速度排名如下:

  1. 带有 C#、C++、C、Java 或类似内容的 Dll 自定义库
  2. VBA
  3. Excel

我比较了VBA vs C++ function here,从长远来看,结果对 VBA 来说真的很糟糕。

所以,下面的斐波那契在 C++ 中递归:

int __stdcall FibWithRecursion(int & x)
{
    int k = 0;
    int p = 0;

    if (x == 0)
        return 0;

    if (x == 1)
        return 1;

    k = x - 1;
    p = x - 2;
    return FibWithRecursion(k) + FibWithRecursion(p);
}

在 Excel 中调用时,比 VBA 中相同的复杂度函数要好得多:

Public Function FibWithRecursionVBA(ByRef x As Long) As Long

    Dim k As Long: k = 0
    Dim p As Long: p = 0

    If (x = 0) Then FibWithRecursionVBA = 0: Exit Function
    If (x = 1) Then FibWithRecursionVBA = 1: Exit Function

    k = x - 1
    p = x - 2

    FibWithRecursionVBA = FibWithRecursionVBA(k) + FibWithRecursionVBA(p)

End Function

【讨论】:

  • 对不起,我不明白你是说 C++ > VBA > Excel 但是 VBA 和 Excel 并没有太大的不同?在处理上述矩阵方面,是否值得在 VBA 中工作。例如。如果我按照之前在 VBA 与 Excel 中提到的计算进行计算,我们是在谈论 VBA 快几秒钟还是快几分钟?
  • @Tom - 在任何情况下,VBA 都比 Excel 快。关于分钟与秒 - 在 Excel 中计算 ((X^T)WX)^(-1)(X^T)WY 5000 次真的需要几分钟吗?
  • 它只计算一次它只是矩阵非常大。我不确定你是否熟悉矩阵计算。
【解决方案2】:

迟到总比不到好: 我使用更大的矩阵,3 或 4 维,大小如 16k x 26 x 5。 我遍历它们以查找数据、应用一两个公式或与其他矩阵组合。

第一,启动宏后,再打开记事本之类的应用程序,你的速度可能会有不错的提升☺!

然后,我猜你切换了屏幕更新等,并打开了自动计算

最后:不要将数据放在单元格中,而不是数组中。 就像这样:

  • Dim Matrix1 as String ===>'如果您也想在其他宏中使用它,请将其放入声明中。记住你不能再做“blabla=activecell.value2”等了!!
  • 在“Sub()”代码中,使用 ReDim Matrix1(1 to a_value, 1 to 2nd_value, ... , 1 to last_value)
  • Matrix1(45,32,63)="你想放什么"

运行后,只需放下

Matrix1(1 to a_value, 1 to 2nd_value,1) 在第一张纸上,

Matrix1(1 to a_value, 1 to 2nd_value,2) 在第二张纸上,等等

再次开启屏幕更新等 通过这种方式,通过避免中间屏幕更新,我的计算从 45 分钟缩短到了 1 分钟 成功了,希望对大家有用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    相关资源
    最近更新 更多