Java集合比C ++容器快吗? [英] Java collections faster than c++ containers?

查看:57
本文介绍了Java集合比C ++容器快吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读对此的评论答案,我看到了这句话.

I was reading the comments on this answer and I saw this quote.

对象实例化和面向对象的功能使用起来非常快(在许多情况下,它们比C ++更快),因为它们是从一开始就设计的.且收集速度很快.即使在大多数优化的C代码方面,标准Java在这一领域也胜过标准C/C ++.

Object instantiation and object-oriented features are blazing fast to use (faster than C++ in many cases) because they're designed in from the beginning. and Collections are fast. Standard Java beats standard C/C++ in this area, even for most optimized C code.

一位用户(我可能会增加很高的声望)大胆地捍卫了这一说法,并指出

One user (with really high rep I might add) boldly defended this claim, stating that

  1. Java中的堆分配比C ++的

  1. heap allocation in java is better than C++'s

并添加了保护Java中的集合的该语句

and added this statement defending the collections in java

并且Java集合比C ++集合要快得多,这在很大程度上归因于内存子系统的不同.

And Java collections are fast compared to C++ collections due largely to the different memory subsystem.

所以我的问题是,这是否真的是真的,如果是的话,为什么Java的堆分配这么快?

So my question is can any of this really be true, and if so why is java's heap allocation so much faster.

推荐答案

这种说法很荒谬;做到这一点的人要么令人难以置信的无知,要​​么令人难以置信的不诚实.在特别是:

This sort of statement is ridiculous; people making it are either incredibly uninformed, or incredibly dishonest. In particular:

  • 两种情况下动态内存分配的速度将取决于动态内存使用的模式,以及执行.对于熟悉该功能的人来说,这是微不足道的两种情况下都使用的算法来编写基准证明他曾经想过要更快.(因此,例如程序使用大型,复杂的图形进行构建,然后将其拆解并重建后,在垃圾回收下通常会运行得更快.作为将永远不会使用足够的动态内存来触发的程序收藏者.使用很少,大型,寿命长的程序手动存储通常会使分配运行得更快管理.)

  • The speed of dynamic memory allocation in the two cases will depend on the pattern of dynamic memory use, as well as the implementation. It is trivial for someone familiar with the algorithms used in both cases to write a benchmark proving which ever one he wanted to be faster. (Thus, for example, programs using large, complex graphs that are build, then torn down and rebuilt, will typically run faster under garbage collection. As will programs that never use enough dynamic memory to trigger the collector. Programs using few, large, long lived allocations will often run faster with manual memory management.)

比较集合时,您必须考虑什么是集合在集合中.如果您要比较的大向量 double ,例如,Java和C ++之间的区别将是可能是轻微的,并且可能以任何一种方式进行.如果您在比较 Point 的大向量,其中 Point 是一个包含以下内容的值类两倍,C ++可能会将Java淘汰出局,因为它使用纯值语义(没有其他动态分配),因为Java需要动态分配每个 Point (而且动态分配的速度总是快于平均分配速度)最快的动态分配).如果Java中的 Point 类正确地设计成可以作为价值(因此是不可变的,例如 java.lang.String ),然后在向量中的 Point 将需要为每个 Point ;在C ++中,您只需分配即可.

When comparing the collections, you have to consider what is in the collections. If you're comparing large vectors of double, for example, the difference between Java and C++ will likely be slight, and could go either way. If you're comparing large vectors of Point, where Point is a value class containing two doubles, C++ will probably blow Java out of the water, because it uses pure value semantics (with no additional dynamic allocation), where as Java needs to dynamically allocate each Point (and no dynamic allocation is always faster than even the fastest dynamic allocation). If the Point class in Java is correctly designed to act as a value (and thus immutable, like java.lang.String), then doing a translation on the Point in a vector will require a new allocation for every Point; in C++, you could just assign.

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

Much depends on the optimizer. In Java, the optimizer works with perfect knowledge of the actual use cases, in this particular run of the program, and perfect knowledge of the actual processor it is running on, in this run. In C++, the optimizer must work with data from a profiling run, which will never correspond exactly to any one run of the program, and the optimizer must (usually) generate code that will run (and run quickly) on a wide variety of processor versions. On the other hand, the C++ optimizer may take significantly more time analysing the different paths (and effective optimization can require a lot of CPU); the Java optimizer has to be fairly quick.

最后,尽管与所有应用程序都不相关,但是C ++可以单线程.在这种情况下,不需要锁定分配器,这在Java中是从来没有的.

Finally, although not relevant to all applications, C++ can be single threaded. In which case, no locking is needed in the allocator, which is never the case in Java.

关于两个编号点:C ++可以使用更多或堆分配器中的算法与Java少.我有使用了 :: operator delete()函数的C ++程序清空,并且内存被垃圾回收了.(如果你的应用程序分配了许多短暂的小对象,例如分配器可能会加快速度.)第二:C ++真正的优势是它的内存模型不需要动态分配所有内容.即使在Java中分配仅花费十分之一的时间将采用C ++(可能是这种情况,如果您仅计算分配,而不是收集器所需的时间扫)),并带有 Point 的大矢量,如上所述,将C ++中的两个或三个分配与数百万个分配进行比较Java中的分配.

With regards to the two numbered points: C++ can use more or less the same algorithms as Java in its heap allocator. I've used C++ programs where the ::operator delete() function was empty, and the memory was garbage collected. (If your application allocates lots of short lived, small objects, such an allocator will probably speed things up.) And as for the second: the really big advantage C++ has is that its memory model doesn't require everything to be dynamically allocated. Even if allocation in Java takes only a tenth of the time it would take in C++ (which could be the case, if you only count the allocation, and not the time needed for the collector sweeps), with large vectors of Point, as above, you're comparing two or three allocations in C++ with millions of allocations in Java.

最后:为什么Java的堆分配这么快?"它不一定是 if 您是否摊销了收集阶段.分配时间本身可以是非常便宜,因为Java(或至少大多数Java实现)使用重定位收集器,这将释放所有内存位于单个连续的块中.至少是部分抵消了收集器中所需的时间:连续性,您必须移动数据,这意味着很多复制.在大多数实现中,这还意味着额外的指针中的间接访问,以及许多避免的特殊逻辑一个线程在寄存器等中具有该地址时发生的问题.

And finally: "why is Java's heap allocation so much faster?" It isn't, necessarily, if you amortise the time for the collection phases. The time for the allocation itself can be very cheap, because Java (or at least most Java implementations) use a relocating collector, which results in all of the free memory being in a single contiguous block. This is at least partially offset by the time needed in the collector: to get that contiguity, you've got to move data, which means a lot of copying. In most implementations, it also means an additional indirection in the pointers, and a lot of special logic to avoid issues when one thread has the address in a register, or such.

这篇关于Java集合比C ++容器快吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆