C++实现的简单哈希表为什么比Java慢:代码或基准测试问题?

这项研究的目标是探索JIT(即时编译)和AOT(提前编译)策略之间的性能差异,并理解它们各自的优缺点。我们不是要声称某一种语言更慢或更糟。
在我们的测试中,使用JIT编译的HotSpot JVM 23展现了更好的结果。而用Clang 18编译的C++、使用native-image编译的GraalVM 23、以及带有-Xcomp标志的HotSpot JVM 23表现较差。我们试图理解为什么会这样,如果可能的话,还想找到提高C++版本性能以匹配Java JIT编译结果的方法。

我们的基准测试比较了Java中简单小型哈希表(map)的实现与C++中逐行等效的实现。我们尽力保证两个实现的一致性。这个目标不是比较标准库中的哈希表实现(java.util.HashMap和std::unordered_map),因为它们当然是用不同的源代码实现的。

基准测试创建一个有20,000个桶的哈希表,并插入2,000,000个对象。我们插入一次,清空map然后再次插入,以利用哈希表的内部对象池。换句话说,第一次插入时,对象将在堆上分配。第二次插入时,对象将重用来自内部对象池的对象。

处理测量的Bench类在两种语言中应该也是等效的。

有鉴于这些细节,有人了解为什么C++ map实现会比Java map实现慢吗?我们有没有忽视某些东西或C++实现的某些方面可以进一步优化?也许有些Clang优化选项我们应该探索?

编辑(@petercordes补充详细描述基准测试内容,并与OP讨论以说明其中一个目标。

C++版本的编写方式使其可以编译成与JVM为Java版本JIT的类似机器代码。如何使Java执行与C++版本相同的机器操作但更快呢?

(编辑者注[@petercordes]: 我已单步执行Hotspot JVM生成的机器代码,确实主循环是链表的线性搜索,使用32位压缩引用对比clang++使用原生指针。通过GDB中断JVM,通常RIP指向代码花费大部分时间的地方。clang++ -O3 … -m32更快,但不仅仅是32位指针,Java对象仍然至少有24字节,而不仅仅是12个字节用于2个引用+一个int。可能与分配模式和缓存未命中相关,因为Java在循环内运行更多机器指令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

应用市场

您的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值