在Java和.NET中,移位比乘法和除法更快吗?

11 浏览
0 Comments

在Java和.NET中,移位比乘法和除法更快吗?

如果你正在使用2的幂次方,左移和右移比大多数甚至所有的CPU上的乘法和除法操作都要快。然而,这可能会降低代码对某些读者和某些算法的清晰度。位移操作对于性能是否真的必要,或者我可以期望编译器或虚拟机注意到这种情况并进行优化(特别是当2的幂次方是一个字面值时)?我主要关心Java和.NET的行为,但也欢迎对其他语言实现的见解。

0
0 Comments

在Java和.NET开发中,有一个问题经常被提及,那就是在位移操作和乘除操作之间,哪个更快。这个问题的出现源于人们试图在编程时预测编译器、JIT(Just-In-Time)编译器以及CPU的优化。然而,事实上,人类在这些情况下都是错误的。现代编译器、JIT编译器以及CPU的优化已经发展到了一个非常高的水平,超出了人们的预测能力。

解决这个问题的方法就是按照你想要实现的目标进行编程,而不是关注如何实现它。因为未来的JIT、虚拟机、编译器和CPU都可能独立地进行改进和优化。如果你过于关注一个微小而具体的细节,那么你就会失去未来所有优化的好处。

所以,当你面临位移操作和乘除操作的选择时,不要试图去猜测哪个更快。相反,你应该选择最适合你的目标和需求的操作。编写出描述你想要实现的目标的代码,而不是试图预测哪个操作更快。

总之,要在编程中考虑到未来的发展,不要过于关注微小而具体的细节。只有这样,你才能充分利用未来的优化和改进。

0
0 Comments

问题的出现原因是因为编译器在优化代码时,会自动将乘法或除法操作转换为位移操作。编译器可以将除以常数的操作转换为乘以一个"魔数"再进行位移操作,这样可以节省大量的时钟周期,因为乘法通常比除法操作快得多。

解决方法是让编译器负责处理微观优化的繁琐细节。多年来,自己进行位移操作已经无法超过编译器的智能。

需要注意的是,如果x是一个奇数负数,x/2x>>1将计算出不同的结果。如果关心计算在奇数负数上的行为,应该使用能够产生正确答案的形式。

Henry Warren的书《Hacker's Delight》提供了大量关于这个主题的信息,并且在配套网站上也有很好的覆盖。遗憾的是,配套网站目前已经无法访问,但可以使用2019年7月17日的快照,该快照似乎是最终的完整快照。

参考链接:

- [Hacker's Delight - Amazon](https://rads.stackoverflow.com/amzn/click/com/0201914654)

- [Hacker's Delight - Companion Website](https://web.archive.org/web/20190717132328/http://www.hackersdelight.org:80/)

- [Reading assembly code](http://www.hexblog.com/?p=17)

0
0 Comments

这篇文章讨论了在Java和.NET中进行位移操作和乘除操作的性能问题。文章的内容主要分为两部分:原因和解决方法。

文章的开头指出,在大多数情况下,优化器会自动进行优化,因此不需要过多考虑位移操作和乘除操作的性能问题。作者强调不要浪费时间在这个问题上,而是应该在真正出现性能问题时再考虑优化。文章中的一句话“你会知道什么时候出现性能问题”强调了这一点。

接下来,文章指出性能问题通常是通过找到一种做更少工作的方式来解决,而不是通过找到一种做同样工作但更快的方式来解决。作者举了一个例子来说明这个观点,强调了性能问题的解决方法。

文章中还有一些评论对原文进行了补充。有人建议使用性能分析器来帮助解决性能问题,还有人认为过早优化是浪费时间。

最后,文章谈到了位移操作和乘除操作的行为差异。如果x可能是一个奇数负数,那么x>>1和x/2的行为是不同的。除非两个操作都是正确的,否则比较它们的速度是没有意义的。文章还提到了在某些情况下,会发现使用x/2而不是x>>=1的情况更常见。

最后一条评论认为,在现代编译器的复杂性和功能下,将位移操作作为性能优化是愚蠢的。

这篇文章讨论了位移操作和乘除操作的性能问题,并强调了不要过早优化的重要性。文章建议在真正出现性能问题时再考虑优化,并使用性能分析器来帮助解决问题。此外,文章还提到了位移操作和乘除操作的行为差异以及现代编译器的复杂性。

0