Jam*_* M. 64 .net c# java optimization bit-manipulation
如果您恰好使用2的幂,则左右移位显然比大多数甚至所有CPU上的乘法和除法运算更快.但是,它可能会降低某些读取器和某些算法的代码清晰度.位移对于性能是否真的是必要的,或者我可以期望编译器或VM注意到这种情况并对其进行优化(特别是当2的幂是文字时)?我主要对Java和.NET行为感兴趣,但欢迎深入了解其他语言实现.
Mic*_*urr 89
今天的大多数编译器将做的不仅仅是转换乘法或除以2的幂来转换操作.在优化时,许多编译器可以优化乘法或除以编译时间常数,即使它不是2的幂.通常乘法或除法可以分解为一系列的移位和加法,如果这一系列操作会更快比乘法或除法,编译器将使用它.
对于除以常数,编译器通常可以将操作转换为乘以"幻数"然后移位的乘法.这可以是主要的时钟周期保护程序,因为乘法通常比除法运算快得多.
Henry Warren的书"Hacker's Delight"有关于这个主题的大量信息,在同伴网站上也有很好的介绍:
另请参阅讨论(带有一个或两个链接):
无论如何,所有这些归结为允许编译器处理微优化的繁琐细节.自从你自己的班次超过编译器以来已经有好几年了.
Jas*_*ton 87
几乎任何有价值的环境都会为您优化这一点.如果没有,你就会有更大的鱼来炸.说真的,不要再浪费一点思考这个.你会知道什么时候出现性能问题.运行探查器后,您将知道导致它的原因,并且应该非常清楚如何修复它.
你永远不会听到有人说"我的应用程序太慢,然后我开始随机更换x * 2,x << 1一切都被修复了!" 性能问题通常通过找到一种方法来减少工作量来解决,而不是通过找到一种方法来快速完成相同的工作.
小智 33
在这些情况下,人类是错误的.
99%,当他们试图猜测现代(和所有未来)编译器时.
当他们试图同时猜测现代(和所有未来)JIT时,99.9%.
当他们试图再次猜测现代(和所有未来的)CPU优化时,99.999%.
以准确描述您想要完成的内容的方式编程,而不是如何编写.未来版本的JIT,VM,编译器和CPU都可以独立改进和优化.如果您指定的内容非常小且具体,那么您将失去所有未来优化的好处.
Gre*_*ill 21
几乎可以肯定的是,对于换档操作,可以依赖于二次幂乘法优化.这是编译器构建的学生将学习的第一个优化之一.:)
但是,我认为没有任何保证.您的源代码应该反映您的意图,而不是试图告诉优化器该做什么.如果您的数量较大,请使用乘法.如果您将一个位域从一个位置移动到另一个位置(想想RGB颜色操作),请使用移位操作.无论哪种方式,您的源代码都将反映您实际在做什么.
izb*_*izb 13
注意,向下移动和除法将(在Java中,当然)给出负数,奇数的不同结果.
int a = -7;
System.out.println("Shift: "+(a >> 1));
System.out.println("Div: "+(a / 2));
Run Code Online (Sandbox Code Playgroud)
打印:
Shift: -4
Div: -3
Run Code Online (Sandbox Code Playgroud)
由于Java没有任何无符号数,因此Java编译器实际上不可能对其进行优化.
小智 8
在我测试的计算机上,整数除法比其他操作慢4到10倍.
当编译器可以用2的倍数替换除法并使你看不出差异时,除以2的倍数的除法明显变慢.
例如,我有一个(图形)程序有许多除以255的许多除法.实际上我的计算是:
r = (((top.R - bottom.R) * alpha + (bottom.R * 255)) * 0x8081) >> 23;
Run Code Online (Sandbox Code Playgroud)
我可以确保它比我以前的计算快得多:
r = ((top.R - bottom.R) * alpha + (bottom.R * 255)) / 255;
Run Code Online (Sandbox Code Playgroud)
所以不,编译器不能做所有的优化技巧.
| 归档时间: |
|
| 查看次数: |
26295 次 |
| 最近记录: |