Che*_*eon 5 java optimization compiler-optimization kotlin
我一直在阅读 Effective Java,3/E。
在阅读有关哈希码的部分时,(第 51 页)我注意到这本书说
31一个很好的特性是乘法可以通过移位,并有更好的表现在某些架构减法来代替:
31 * i == (i << 5) - i。现代虚拟机会自动进行这种优化。
我认为这是有道理的。我想知道当这种优化发生时,代码会变得多快。所以我写了一个简短的代码来看看这种优化的影响。
但是,似乎没有明显的差异。所以我写了更简单的代码,以检查是否发生了这种优化。
下面是我的示例代码。
fun main() {
val num = Random.nextInt()
val a = num * 30
val b = num * 31
val c = num * 32
println("$a, $b, $c")
}
Run Code Online (Sandbox Code Playgroud)
这是编译后的机器代码,来自 IntelliJ 的 Kotlin 字节码功能。
L1
LINENUMBER 5 L1
ILOAD 0
BIPUSH 30
IMUL
ISTORE 1
L2
LINENUMBER 6 L2
ILOAD 0
BIPUSH 31
IMUL
ISTORE 2
L3
LINENUMBER 7 L3
ILOAD 0
BIPUSH 32
IMUL
ISTORE 3
Run Code Online (Sandbox Code Playgroud)
显然,没有区别。我们推送每个号码,然后调用IMUL。我想也许优化发生在Java字节码被编译成实际机器码时,但我从来没有检查过那一面,所以我不知道如何证实我的理论。我搜索了一下,似乎我要找的关键字是 JIT 编译器,它似乎将 .class 转换为特定于 cpu 的机器代码。
我想,也许我可以尝试通过 JIT 编译器将此代码转换为特定于 cpu 的机器代码,但这意味着我在一个特定的 CPU 上检查了这个理论,而不是所有的 CPU。我想看看它是否“大致正确”,但这会花费太多时间。
那么,有没有办法确认上面的代码实际上(通常)被编译器优化了?如果我以后有类似的问题,我应该去哪里寻找?我的意思是,当我对 java 行为感到好奇时,我会去 oracle 并检查 JVM 引用或 java se 引用。但是编译器的行为呢?我应该从哪里开始?
这是一个很长的问题。感谢您花宝贵的时间阅读这个问题。
(只是一个补充说明)
我在https://godbolt.org/上检查了 C 和 python ,并确认对于 C,它实际上是优化的。
L1
LINENUMBER 5 L1
ILOAD 0
BIPUSH 30
IMUL
ISTORE 1
L2
LINENUMBER 6 L2
ILOAD 0
BIPUSH 31
IMUL
ISTORE 2
L3
LINENUMBER 7 L3
ILOAD 0
BIPUSH 32
IMUL
ISTORE 3
Run Code Online (Sandbox Code Playgroud)
test:
push rbp
mov rbp, rsp
sub rsp, 32
mov DWORD PTR [rbp-20], edi
call rand
mov DWORD PTR [rbp-4], eax
mov eax, DWORD PTR [rbp-4]
imul eax, eax, 30
mov DWORD PTR [rbp-8], eax
mov edx, DWORD PTR [rbp-4]
mov eax, edx
sal eax, 5
sub eax, edx
mov DWORD PTR [rbp-12], eax
mov eax, DWORD PTR [rbp-4]
sal eax, 5
mov DWORD PTR [rbp-16], eax
mov eax, DWORD PTR [rbp-8]
imul eax, DWORD PTR [rbp-12]
imul eax, DWORD PTR [rbp-16]
leave
ret
Run Code Online (Sandbox Code Playgroud)
但是,python 不是。
int test(int num) {
int n = rand();
int a= n*30;
int b= n*31;
int c= n*32;
return a * b * c;
}
Run Code Online (Sandbox Code Playgroud)
5 18 LOAD_NAME 2 (num)
20 LOAD_CONST 2 (30)
22 BINARY_MULTIPLY
24 STORE_NAME 3 (a)
6 26 LOAD_NAME 2 (num)
28 LOAD_CONST 3 (31)
30 BINARY_MULTIPLY
32 STORE_NAME 4 (b)
7 34 LOAD_NAME 2 (num)
36 LOAD_CONST 4 (32)
38 BINARY_MULTIPLY
40 STORE_NAME 5 (c)
42 LOAD_CONST 5 (None)
44 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131 次 |
| 最近记录: |