java - 为什么这个 GoLang 解决方案比等效的 Java 解决方案更快?

标签 java performance go

最近在工作中,我们正在玩 IBM 提出的以下测验问题 https://www.research.ibm.com/haifa/ponderthis/challenges/May2015.html

经过一番努力,我和一位同事得出了两种解决方案,一种是 GoLang https://gist.github.com/walesey/e2427c28a859c4f7bc920c9af2858492#file-main-go-L57另一个是 Java https://gist.github.com/boyter/42df7f203c0932e37980f7974c017ec5#file-puzzle-java-L63使用 Java 中的 playGames 和 GoLang 中的游戏(两者都在上面链接)的性能关键方法。

Go 程序几乎是 Java 程序的文字副本,但它的运行时间约为 6 秒,而 Java 程序约为 26 秒(在我的本地机器上)。在其他几台机器上也复制了类似的数字,Go 程序的速度大约快了 5 倍。

Go 程序使用 1.7.5 编译,Java 使用 1.8.0_65 版本在 2013 年末配备 2.6GHz i5 CPU 的视网膜 Macbook Pro 上运行 macOS Sierra 10.12.3。

当大多数基准测试表明 Java 应该具有大致相同的运行时间时,为什么 Go 程序比 Java 程序快 5 倍?这只是循环中的基本数学运算,因此它们似乎应该在同一时间运行。对于 JVM 启动时间,我可以理解一秒钟左右,但这似乎不对。

两个程序使用几乎相同的循环。游戏结果的所有可能排列都是针对每个起始金额创建和迭代的。似乎 Go 在主循环中运行的任何数量的循环操作都围绕 Java 运行。

我知道这是一个“微型”基准测试,但我想知道为什么 Go 代码的性能大大优于 Java 代码。仅仅是 Go for simple loops/math 更高效,因此更快吗?它是否能够展开循环(尽管这似乎不太可能产生如此巨大的差异)?

如果不是,您应该如何构建 Java 程序以从简单的循环和数学运算中获得最大的性能?

编辑 - 感谢Dolda2000,我修改了Java 版本。现在它的速度与 GoLang 版本差不多。事实上,问题在于游戏的创建导致 Java 版本必须模拟更多游戏以确定游戏是否持续足够长的时间。经过这些更改,它现在可以在大约 6 秒内运行,并恢复了我对 Java 的信心。

更新 - 这里是 expanded essay其中更详细地讨论了这个问题的背景。

最佳答案

事实证明,您的程序并不像您认为的那样平等。我对他们进行了检测,以查看他们模拟了多少场比赛(即个人投注轮次),而 Go 版本模拟了 1 612 629 805 场比赛,而 Java 版本模拟了 12 323 903 502 场比赛,几乎多出一个数量级。

在我的机器上,关闭多线程以获得更可预测的结果,Java 程序运行大约 75 秒,Go 程序运行 12.5 秒。将其与总运行时间相匹配,看起来 Java 程序实际上在每个模拟游戏中略,大约为 6.1 ns,而围棋程序为 7.8 ns。

不过,尚不确定为什么他们会模拟如此大量不同的游戏。也许 Go 版本生成轮次的方式只是碰巧找到了更快的终止。

编辑:实际上,最后的猜测很有道理。 Go 版本从调整游戏的初始回合开始,而 Java 版本从调整游戏的最后回合开始(换句话说,将回合列表视为递增的 11 位 base-3 列表)数字,Go 版本是 little-endian,而 Java 版本是 big-endian,可以这么说),因此 Java 版本必须通过更多相同的开始来模拟终止的变体。我没有尝试验证这个假设,但我对此非常确定,我觉得没有必要。

关于java - 为什么这个 GoLang 解决方案比等效的 Java 解决方案更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43082115/

相关文章:

java - Swagger @ApiOperation 可以允许在 Java 中指定列表列表吗?

java - 如何在android中使用RSA进行加密和解密

java - 如何使用 HashMap 将多个值放入 ArrayList?

python - 哪个更快?检查某个东西是否在 Python 列表中? IE。成员(member)与非成员(member)

PHP/MySQL : Combine UPDATE queries?

go - 在 Go 中解析动态时间格式

ssl - 获取网络/http : TLS handshake timeout golang

java - 我用IDEA将对象序列化到文件中,但是无论我设置什么格式,打开文件都是乱码

java - 当我使用 cfdocument 时,ColdFusion 挂起

json - 在go lang中循环/迭代第二级嵌套JSON