Java集合比c ++容器更快?

aar*_*man 26 c++ java heap collections performance

我正在阅读关于这个答案的评论,我看到了这个引用.

对象实例化和面向对象的特性使用起来非常快(在许多情况下比C++更快)因为它们从一开始就被设计出来.和收藏很快.标准Java在该领域击败标准C/C++,即使对于大多数优化的C代码也是如此.

一个用户(我可能会添加很高的代表)大胆地为这个说法辩护,说明这一点

  1. java中的堆分配比C++好

  2. 并添加此语句来保护java中的集合

    由于内存子系统不同,Java集合与C++集合相比也很快.

所以我的问题是,任何这些都是真的,如果是这样,为什么java的堆分配要快得多.

Jam*_*nze 43

这种说法很荒谬; 制作它的人要么是难以置信的不知情,要么是不可思议的不诚实.特别是:

  • 两种情况下动态内存分配的速度取决于动态内存使用模式以及实现.对于熟悉两种情况下使用的算法的人来说,编写一个他想要更快的基准证明是微不足道的.(因此,例如,使用构建,然后拆除和重建的大型复杂图形的程序通常在垃圾收集下运行得更快.程序从不使用足够的动态内存来触发收集器.程序使用很少,大,通过手动内存管理,长期分配通常会运行得更快.)

  • 比较集合时,您必须考虑集合中的内容.double例如,如果您要比较大型向量 ,Java和C++之间的差异可能会很小,并且可以采用任何一种方式.如果你要比较大的向量Point,其中Point是一个包含两个双精度的值类,C++可能会将Java从水中吹走,因为它使用纯值语义(没有额外的动态分配),而Java需要动态分配每个 Point(并且没有动态分配总是比最快的动态分配更快).如果PointJava中的类被正确设计为充当值(因而不可变java.lang.String),那么 Point在向量中进行转换将需要为每个进行新的分配 Point; 在C++中,你可以只分配.

  • 很大程度上取决于优化器.在Java中,优化器在这个特定的程序运行中完美地了解实际用例,并在此运行中完全了解它运行的实际处理器.在C++中,优化器必须使用来自分析运行的数据,该分析运行永远不会完全对应于程序的任何一次运行,并且优化器必须(通常)生成将在各种处理器上运行(并快速运行)的代码版本.另一方面,C++优化器可能会花费更多的时间来分析不同的路径(有效的优化可能需要大量的CPU); Java优化器必须相当快.

  • 最后,虽然与所有应用程序无关,但C++可以是单线程的.在这种情况下,分配器中不需要锁定,这在Java中绝不是这种情况.

关于两个编号点:C++在其堆分配器中可以使用与Java相同的算法.我已经使用了::operator delete()函数为空的C++程序,并且内存被垃圾收集.(如果您的应用程序分配大量的短暂,小物件,这样的分配可能会加快速度.)至于第二:真正的大 ++有优势C是它的内存模型并不需要的一切动态分配.即使Java中的分配只需要C++中的十分之一时间(可能是这种情况,如果你只计算分配,而不是收集器扫描所需的时间),使用大的向量Point,如上所述,您将C++中的两个或三个分配与Java中的数百万个分配进行比较.

最后:"为什么Java的堆分配要快得多?" 如果您分摊收集阶段的时间,不一定如此.分配本身的时间可能非常便宜,因为Java(或至少大多数Java实现)使用重定位收集器,这导致所有空闲内存都在一个连续的块中.这至少部分地被收集器所需的时间所抵消:为了获得连续性,你必须移动数据,这意味着需要大量的复制.在大多数实现中,它还意味着指针中的附加间接,以及许多特殊逻辑,以避免在一个线程在寄存器中具有地址时出现问题.

  • 我认为考虑*在将两种语言相互称重时需要*时间是很重要的.一次性初始编译是开发人员时间,运行时延迟是用户时间; 在大多数情况下,目标是最小化后者,但在任何情况下,用户至少都不了解开发人员,而且两者是不同的野兽. (2认同)

Jas*_*n C 30

你的问题没有具体的答案.例如,C++根本没有定义内存管理.它将分配细节留给库实现.因此,在C++的范围内,给定的平台可能具有非常慢的堆分配方案,如果绕过它,Java肯定会更快.在另一个平台上,内存分配可能非常快,优于Java.正如James Kanze所指出的,Java 对内存管理的限制很少(例如,即使GC算法完全取决于JVM实现者).因为Java和C++没有对内存管理施加约束,所以没有针对该问题的具体答案.C++专门针对底层硬件和内核函数开放,而Java则是有目的地开放JVM内存管理.所以问题变得非常模糊.

您可能会发现某些操作在Java中更快,而有些则没有.但是,在你尝试之前,你永远不会知道:

在实践中,真正的区别在于您的更高级别的算法和实现.对于除了最绝对性能关键的应用之外的所有应用,与算法本身的性能特征相比,不同语言中相同数据结构的性能差异完全可以忽略不计.专注于优化更高级别的实施.只有在您完成此操作之后,并且在确定未满足性能要求之后,并且在您进行基准测试并发现(不太可能)您的瓶颈在容器实现中之后,您是否应该开始考虑这样的事情.

通常,只要您发现自己在思考或阅读有关C++与Java问题的内容,请立即停止并重新关注有效的事物.

  • 除了我没有设计一个性能关键应用程序,我只是好奇 (7认同)
  • 嗯你的观点是有效的我只是不喜欢你的回答,我很高兴我基本上问了问题_是java比c ++更快_并且侥幸逃脱 (4认同)

kri*_*ant 15

Java堆更快,因为(简化)您需要做的就是分配增加堆顶部指针(就像在堆栈上一样).这是可能的,因为堆会定期压缩.所以你的速度价格是:

  1. 定期GC暂停堆压缩
  2. 增加内存使用量

没有免费的奶酪......因此,虽然收集操作可能很快,但是在GC工作期间整体减速可以分摊.

  • 但是要回答另一半,因此 Java 集合实际上更快吗? (2认同)

Pet*_*rey 10

虽然我是Java的粉丝,但值得注意的是C++支持在堆栈上分配对象,这比堆分配更快.

如果你有效地使用C++以各种方式做同样的事情,那么它将比Java更快(即使你需要更长时间才能找到最佳组合)

如果您像在Java中一样使用C++编程,例如堆上的所有内容,所有虚拟方法都有大量的运行时检查,这些检查无法执行任何操作并且可以动态优化,速度会慢一些.Java进一步优化了这些东西,因为这些是a)是Java唯一做的事情,b)可以更有效地动态优化,c)Java具有较少的功能和副作用,因此优化器更容易获得合适的速度.

  • 相信我,不打算 (3认同)
  • 如果你只使用原语,java中的所有内容都将在堆栈中 (2认同)
  • 除此之外:所有STL容器都允许您提供自定义分配器,因此如果您需要,可以提供基于例如alloca()的分配器以保留堆栈中的所有内容,或者您​​可以预先在堆上分配块并提供自定义具有您自己的内存模型的分配器. (2认同)
  • @PeterLawrey很棒的一点.另外,值得注意的是C++实际上并没有定义内存模型,细节留给了实现者; 可以想象,一个平台可能具有糟糕的堆分配性能,另一个平台可能非常快速,另一个可以针对并发访问进行优化等.这使得有关C++与Java内存模型性能的问题很难回答 - 更具体的问题是"平台X上的C++,运行时实现Y与Java". (2认同)