1

这个 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 和 GCC

对于 VBA,我使用 Excel 2010。

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

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

4

4 回答 4

4

您的基准已关闭,边距应该更大。

例如,在我的计算机上,C++ 代码需要 7.46 秒(未经优化编译,使用 Unixtime工具计时);相比之下,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 代码的中间表示,而不是逐行代码解释。

于 2012-12-12T22:39:15.977 回答
1

区别很常见,最大的区别是C++是编译的。我很惊讶差异没有大几个数量级。大多数性能基准测试显示 C/C++ 比脚本语言快 10 倍以上。你是如何编译 C++ 代码的?我敢打赌,如果以最高级别的优化编译,它会在 5-10 秒内运行。如果你还没有,你应该用一个-O3标志编译并计时。

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

于 2012-12-12T22:34:54.860 回答
1

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

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

于 2012-12-12T22:35:54.837 回答
0

我想用外行的话想象一下VB是如何构建的,在它下面是利用以前用C++开发的东西。所以,不管你如何分割它,在大多数情况下,VB 所做的一切都有一个隐藏的 C++“中间人”,所以某些事情本质上会被做两次,例如那些内置的错误保护、interps 等。

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

于 2017-03-24T08:57:25.673 回答