简单算术运算(VBA与C ++)之间运行时差异的主要原因是什么?

时间:2012-12-12 22:27:51

标签: c++ performance vba

这个C ++程序需要20到25秒才能在我相对较慢的计算机上运行:

#include <iostream>

int main()
{
int i;
double test = 456;

for (i = 0; i < 900000000; i++) {
    test = (test / 0.99999999);
}
    std::cout << "The value of test is " << test <<".\n";
    return 0;
}

这个excel vba宏需要37到40秒才能在我相对较慢的计算机上运行:

Sub Macro1()
Dim i As Long
Dim test As Double
test = 456

For i = 0 To 900000000
    test = (test / 0.99999999)
Next i

Cells(1, 1).Value = test
End Sub

这种差异是典型的(C ++与非编译语言)吗?导致这种时间差异的主要因素是什么?事实上C ++编译是最重要的因素吗?感谢。

的信息:

对于C ++,我使用了Code :: Blocks with GCC

对于VBA,我使用的是Excel 2010。

对于Code :: Blocks,它在控制台中有一个内置的计时器。

对于excel,我使用了一个iPhone秒表(感觉不像使用CHighResTimer http://www.ozgrid.com/forum/showthread.php?t=56900

4 个答案:

答案 0 :(得分:4)

您的基准关闭,保证金应该更大。

例如,在我的计算机上,C ++代码需要7.46秒(没有优化编译,使用Unix time工具计时);相比之下,VBA代码需要46秒。这是一个更现实的边缘(但我不会对更大的一个感到惊讶 - 传统的,非优化的解释器通常至少慢十倍)。

首先,VBA首先必须读入代码并逐行解释或将其转换为中间表示。不过,这个中间代码表示仍然是解释,不是由CPU直接运行(或者你是否计算了C ++中的编译时间?)。 1

此外,VB(A)在这段代码中做了很多冗余的东西,这在C ++中是不存在的:例如,每一个整数加法(在For循环的增量中隐含在你的代码中变量)防止溢出。基本上,这个VB代码

i = i + 1

转换为以下伪中间代码:

if i + 1 overflows then
    raise an overflow error
end if
i = i + 1

...用于每个整数运算。这消耗了大量的运行时间。对于数组(或此处:单元格)访问操作也是如此。


1 认为 VBA使用名为 P-code 的中间表示,而不是逐行代码解释。

答案 1 :(得分:1)

区别很普遍,最大的区别是C ++是编译的。我很惊讶,差异并不大于数量级。大多数性能基准测试表明C / C ++比脚本语言快10倍以上。你是如何编译C ++代码的?我敢打赌,如果在最高级别的优化中编译,它将在5-10秒内运行。如果您还没有,则应使用-O3标志进行编译并计时。

我对VBA了解不多,但如果您正在使用完全优化编译C ++,我认为VBA更有可能通过即时编译器运行,然后在CLR上执行与VB.NET相同的操作。你展示的性能更像是VC ++与VB.NET,而不是VC ++与任何脚本语言。

答案 2 :(得分:1)

我不相信VBA中的代码行会一遍又一遍地被解释,必须有一些缓存,否则因子会比1:2大得多。

可能存在许多差异。当然,从高级语言到CPU指令的转换在不同语言之间是不同的。 C ++编译器针对性能进行了优化,以满足各种应用程序的需求,这在Office产品中可能并不那么重要。

答案 3 :(得分:0)

我想用外行的术语来想象VB是如何构建的,在它下面它正在挖掘以前用C ++开发的东西。 sO,无论你如何解决,在大多数情况下VB都会有一个隐藏的C ++“中间人”,所以某些事情本质上已经完成了两次,例如内置错误保护,interps等等。

我还发现VBA作为标准项目或使用AutoCAD VBA构建到进程DLL中的相同功能有所不同,但没有时间性能差异,但我可以看到进程内运行速度更快,因为在VBA中也是如此比从外部VB连接到AutoCAD运行得更快。似乎在VBA中为你分配了可用的内存,VB正在使用它自己的进程,我不知道,但它是一个可以考虑提高速度的地方。