Declaring/initializing 双(或多)循环内部或外部的变量
Declaring/initializing variables inside or outside of a double (or multiple) loop
根据 similar question 和多次 Google 搜索,在循环外或循环内声明或初始化变量 "might" 在性能方面是相同的。
我正在 运行 进行计算机模拟,我正在尝试尽可能地优化代码,因为它必须 运行 很多次并且它有多个内部循环很多迭代。
我想知道是否值得将所有变量移出循环。我有很多 "theoretically" 不断被重新声明的变量。我说 "theoretically" 是因为我不知道 Java 编译器是否真的优化代码并在比方说方法级别声明所有内容。
基本上,什么会更有效率?代码 A 还是代码 B?
代码A:
private void codeA() {
double a = 0.0;
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
代码 B:
private void codeA() {
double a;
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
代码 C:
private void codeC() {
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
double a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
我只是在这个例子中使用了变量a,但是计算机模拟使用了更多。我的大部分变量都是原始变量(int、double、float)。为了提高性能而在循环外声明原语是否有意义?
javac
不会优化。在所有 3 个案例中生成的字节码 is different。 (javac Test.java
编译并且 javap -c Test.class
显示字节码)
Java 虚拟机可能会优化。
JMH 基准显示明显的赢家:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testA thrpt 20 423.437 ± 6.745 ops/s
MyBenchmark.testB thrpt 20 337.728 ± 56.363 ops/s
MyBenchmark.testC thrpt 20 351.419 ± 70.290 ops/s
单位是每秒的操作次数,越多越好。 Benchmark source code。使用了 OpenJDK IcedTea 2.5.4 Java 虚拟机。
所以,在外部声明和初始化变量应该是最有效的。
根据 similar question 和多次 Google 搜索,在循环外或循环内声明或初始化变量 "might" 在性能方面是相同的。
我正在 运行 进行计算机模拟,我正在尝试尽可能地优化代码,因为它必须 运行 很多次并且它有多个内部循环很多迭代。
我想知道是否值得将所有变量移出循环。我有很多 "theoretically" 不断被重新声明的变量。我说 "theoretically" 是因为我不知道 Java 编译器是否真的优化代码并在比方说方法级别声明所有内容。
基本上,什么会更有效率?代码 A 还是代码 B?
代码A:
private void codeA() {
double a = 0.0;
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
代码 B:
private void codeA() {
double a;
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
代码 C:
private void codeC() {
for (int i1 = 0; i < i1_N; i1++ ) {
// Many other loops
for (int im = 0; i < im_N; im++ ) {
double a = 0; // a is used for the first time
for (int in = 0; i < in_N; in++ ) {
a++; // calculate something with a
}
}
// close many other loops
}
}
我只是在这个例子中使用了变量a,但是计算机模拟使用了更多。我的大部分变量都是原始变量(int、double、float)。为了提高性能而在循环外声明原语是否有意义?
javac
不会优化。在所有 3 个案例中生成的字节码 is different。 (javac Test.java
编译并且 javap -c Test.class
显示字节码)
Java 虚拟机可能会优化。
JMH 基准显示明显的赢家:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testA thrpt 20 423.437 ± 6.745 ops/s
MyBenchmark.testB thrpt 20 337.728 ± 56.363 ops/s
MyBenchmark.testC thrpt 20 351.419 ± 70.290 ops/s
单位是每秒的操作次数,越多越好。 Benchmark source code。使用了 OpenJDK IcedTea 2.5.4 Java 虚拟机。
所以,在外部声明和初始化变量应该是最有效的。