问题描述
确定数字甚至使用Java的最有效方法是什么?为什么?
What would be the most efficient manner to determine that a number is even using Java, and why?
会使用模数或减法,还是我实际上没有想到的其他方式?
Would it be using modulo or subtraction, or some other manner that I haven't actually thought of?
一个人想象我可以通过一个简单的测试类来确定这一点-我可以-但这真的不能解释为什么,会吗?
One imagines I could determine this doing a simple test class - and I can - but that really wouldn't explain why, would it?
我并没有为提高处理 许多项目的崇高目标而做一些疯狂的裤子性能调整.但是我很好奇,是否应该将一种方法 优先于另一种方法,并将其作为常规做法.同样,我们不会使用&
代替&&
,为什么在可以使用&
时为什么使用%
?
I'm not doing some crazy-pants performance tuning for some lofty goal of processing that many items faster. But I was curious if one method should be preferred over the other as common practice. In the same way we wouldn't use &
in place of &&
, why use %
when we can use &
?
推荐答案
如果检查以下两种方法的热点7生成的程序集:
If you check the assembly generated by hotspot 7 of these two methods:
public static boolean isEvenBit(int i) {
return (i & 1) == 0;
}
public static boolean isEvenMod(int i) {
return i % 2 == 0;
}
您将看到,虽然mod进行了优化,并且基本上按位执行了and
,但是由于两个操作并非严格等效,因此它具有一些额外的说明*.其他JVM可能会对其进行不同的优化.该程序集发布在下面以供参考.
you will see that although the mod is optimised and basically does a bitwise and
but it has a few extra instructions because the two operations are not strictly equivalent*. Other JVMs might optimise it differently. The assembly is posted below for reference.
我还运行了一个微基准测试,它证实了我们的观察结果:isEventBit稍快一些(但是两者都运行大约2个纳秒,因此整个典型程序可能不会受到太大影响) ):
I also ran a micro benchmark which confirms our observation: isEventBit is marginally faster (but both run in about 2 nanoseconds so probably won't have much of an inmpact on a typical program as a whole):
Benchmark Mode Samples Score Error Units
c.a.p.SO16969220.isEvenBit avgt 10 1.869 ± 0.069 ns/op
c.a.p.SO16969220.isEvenMod avgt 10 2.554 ± 0.142 ns/op
isEvenBit
# {method} 'isEvenBit' '(I)Z' in 'javaapplication4/Test1'
# parm0: rdx = int
# [sp+0x20] (sp of caller)
0x00000000026c2580: sub rsp,0x18
0x00000000026c2587: mov QWORD PTR [rsp+0x10],rbp ;*synchronization entry
; - javaapplication4.Test1::isEvenBit@-1 (line 66)
0x00000000026c258c: and edx,0x1
0x00000000026c258f: mov eax,edx
0x00000000026c2591: xor eax,0x1 ;*ireturn
; - javaapplication4.Test1::isEvenBit@11 (line 66)
0x00000000026c2594: add rsp,0x10
0x00000000026c2598: pop rbp
0x00000000026c2599: test DWORD PTR [rip+0xfffffffffdb6da61],eax # 0x0000000000230000
; {poll_return}
0x00000000026c259f: ret
isEvenMod
# {method} 'isEvenMod' '(I)Z' in 'javaapplication4/Test1'
# parm0: rdx = int
# [sp+0x20] (sp of caller)
0x00000000026c2780: sub rsp,0x18
0x00000000026c2787: mov QWORD PTR [rsp+0x10],rbp ;*synchronization entry
; - javaapplication4.Test1::isEvenMod@-1 (line 63)
0x00000000026c278c: mov r10d,edx
0x00000000026c278f: and r10d,0x1 ;*irem
; - javaapplication4.Test1::isEvenMod@2 (line 63)
0x00000000026c2793: mov r11d,r10d
0x00000000026c2796: neg r11d
0x00000000026c2799: test edx,edx
0x00000000026c279b: cmovl r10d,r11d
0x00000000026c279f: test r10d,r10d
0x00000000026c27a2: setne al
0x00000000026c27a5: movzx eax,al
0x00000000026c27a8: xor eax,0x1 ;*ireturn
; - javaapplication4.Test1::isEvenMod@11 (line 63)
0x00000000026c27ab: add rsp,0x10
0x00000000026c27af: pop rbp
0x00000000026c27b0: test DWORD PTR [rip+0xfffffffffdb6d84a],eax # 0x0000000000230000
; {poll_return}
0x00000000026c27b6: ret
正如注释中指出的,
这篇关于在Java中检测偶数的最有效方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!