gpt4 book ai didi

java - 将一个 int 乘以 30、31、32 - 这些真的被编译器优化了吗? (有效的java这么说)

转载 作者:行者123 更新时间:2023-12-01 12:47:47 26 4
gpt4 key购买 nike

我一直在阅读 Effective Java,3/E。
在阅读有关哈希码的部分时,(第 51 页)我注意到这本书说

A nice property of 31 is that the multiplication can be replaced by a shift and a subtraction for better performance on some architectures: 31 * i == (i << 5) - i. Modern VMs do this sort of optimization automatically.


我认为这是有道理的。我想知道当这种优化发生时代码会变得多快。所以我写了一个简短的代码来看看这种优化的影响。
但是,似乎没有明显的差异。所以我写了更简单的代码,来检查这种优化是否发生了。
下面是我的示例代码。
fun main() {
val num = Random.nextInt()
val a = num * 30
val b = num * 31
val c = num * 32

println("$a, $b, $c")
}
这是编译后的机器代码,来自 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
显然,没有区别。我们推送每个号码,然后调用 IMUL .我想也许优化发生在Java字节码被编译成实际的机器码时,但我从来没有检查过那方面,所以我不知道如何证实我的理论。我搜索了一下,似乎我正在寻找的关键字是 JIT 编译器,它似乎将 .class 转换为特定于 cpu 的机器代码。
我想,也许我可以尝试通过 JIT 编译器将此代码转换为特定于 cpu 的机器代码,但这意味着我在一个特定的 CPU 上检查了这个理论,而不是所有的 CPU。我想看看它是否“普遍正确”,但这需要太多时间。
那么,有没有办法确认上面的代码实际上(通常)被编译器优化了?
如果我以后有类似的问题,我应该去哪里寻找?我的意思是,当我对 java 的行为感到好奇时,我会去 oracle 并检查 JVM 引用或 java se 引用。但是编译器的行为呢?我应该从哪里开始?
那是一个很长的问题。感谢您花费宝贵的时间阅读此问题。
(只是一个附加说明)
我在 https://godbolt.org/ 上检查了 C 和 python ,并确认对于C,它实际上是优化的。
int test(int num) {
int n = rand();
int a= n*30;
int b= n*31;
int c= n*32;
return a * b * c;
}
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
但是,python 不是。
num = randint()

a = num * 30
b = num * 31
c = num * 32
  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

最佳答案

C 这样的语言编译Ahead-Of-Time ,这意味着所有优化都在 中完成编译时间因为它们被编译为 assembly code并由本地机器解释。
Kotlin , Scala , JavaJVM languagesJava Virtual Machine 上运行. JVM 的实现确实 运行时间 优化。这称为 Just-In-Time Compilation . JIT 编译器的一个例子是 HotSpot ,就像它的名字一样,它会发现 JVM 代码的“热点”,并将其编译和优化为汇编。 HotSpot 的替代 JIT 是 OpenJ9 .
Python 这样的语言,我相信是 interpreted at runtime这意味着根本不涉及任何优化。但是python的AOT编译器实际上可能会做一些优化,但我真的不知道这些编译器的实现细节。

关于java - 将一个 int 乘以 30、31、32 - 这些真的被编译器优化了吗? (有效的java这么说),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62740462/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com