eba*_*onp 4 c++ java performance
这个问题只是推测性的.
我在C++中有以下实现:
using namespace std;
void testvector(int x)
{
vector<string> v;
char aux[20];
int a = x * 2000;
int z = a + 2000;
string s("X-");
for (int i = a; i < z; i++)
{
sprintf(aux, "%d", i);
v.push_back(s + aux);
}
}
int main()
{
for (int i = 0; i < 10000; i++)
{
if (i % 1000 == 0) cout << i << endl;
testvector(i);
}
}
Run Code Online (Sandbox Code Playgroud)
在我的框中,这个程序大约执行.12秒; 令人惊讶的是,我在Java中使用了类似的实现[使用String和ArrayList],它的运行速度比我的C++应用程序快了很多(大约2秒).
我知道Java HotSpot在转换为native时会执行很多优化,但我认为如果这样的性能可以用Java完成,它也可以用C++实现......
那么,你认为应该在上面的程序中修改,或者我不知道,在使用的库中或在内存分配器中,在这个东西中达到类似的性能?(写这些东西的实际代码可能会很长,因此,讨论它会很棒)...
谢谢.
Dan*_*ker 12
你必须小心性能测试,因为它很容易欺骗自己或者不喜欢比较.
但是,我已经看到了将C#与C++进行比较的类似结果,并且有许多着名的博客文章关于当遇到这种证据时本机编码器的惊讶.基本上,一个好的现代代压缩GC非常适合大量的小型分配.
在C++的默认分配器中,每个块都被视为相同,因此分配和释放的平均成本非常高.在分代GC中,所有块都非常非常便宜地分配(几乎和堆栈分配一样便宜),如果它们变得短暂,那么它们的清理也非常便宜.
这就是为什么与更现代的语言相比,C++的"快速性能" - 在很大程度上 - 是神话.您必须先将C++程序从所有识别中调整好,然后才能与同等天真编写的C#或Java程序的性能竞争.
您的所有程序都以1000步为单位打印数字0..9000.testvector()不执行任何操作的调用可以消除.我怀疑你的JVM注意到了这一点,并且实际上是在优化整个功能.
只需将调用注释掉即可在C++版本中实现类似的效果testvector()!
嗯,这是一个非常无用的测试,只测量小对象的分配.也就是说,简单的改变使我的运行时间从大约15秒减少到大约4秒.新版本:
typedef vector<string, boost::pool_allocator<string> > str_vector;
void testvector(int x, str_vector::iterator it, str_vector::iterator end)
{
char aux[25] = "X-";
int a = x * 2000;
for (; it != end; ++a)
{
sprintf(aux+2, "%d", a);
*it++ = aux;
}
}
int main(int argc, char** argv)
{
str_vector v(2000);
for (int i = 0; i < 10000; i++)
{
if (i % 1000 == 0) cout << i << endl;
testvector(i, v.begin(), v.begin()+2000);
}
return 0;
}
real 0m4.089s
user 0m3.686s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
Java版本有时间:
real 0m2.923s
user 0m2.490s
sys 0m0.063s
Run Code Online (Sandbox Code Playgroud)
(这是我原始程序的直接java端口,除了它将ArrayList作为参数传递以减少无用的分配).
总而言之,Java上的小分配速度更快,内存管理在C++中更麻烦一些.但我们已经知道了:)