Java - 内联代码会有好处吗?
Java - Will inlining code have benefits?
我做了一些研究,但我主要看到的是 C++ 答案。我最接近的是 this. I also saw this page 但它并没有真正解释任何东西。
如果我使用第二段代码有什么优势吗?会有明显的性能差异吗?内存呢?如果重复做怎么办?
现在我有这个功能。我确信这样做的好处是代码可读性:
private static Bitmap resize(Bitmap image, int maxWidth) {
float widthReducePercentage = ((float) maxWidth / image.getWidth());
int scaledHeight = Math.round(image.getHeight() * widthReducePercentage);
return Bitmap.createScaledBitmap(image, maxWidth, scaledHeight, true);
}
现在,我有了第二段代码:
private static Bitmap resize(Bitmap image, int maxWidth) {
return Bitmap.createScaledBitmap(image, maxWidth, Math.round(image.getHeight() * (float) maxWidth / image.getWidth()), true);
}
一个更简单的例子是:
for(;;) {
String foo = "hello";
Console.print(foo + "world");
}
对比
for(;;) {
Console.print("hello" + "world");
}
他们都是一样的。前者只是比后者更清楚。
在某些情况下,例如下面的块,单行代码很有用。
public boolean isEmpty() {
return getCount() != 0;
}
如果您想让它更易于阅读,尤其是涉及方程式时,请选择 variable
。一行使其简单和简短,但有利于简短和简单的逻辑。
这是我个人的看法。
首先:这不是"inlining"的意思。参见:What is inlining?
其次:不,性能不会有任何可衡量的差异。在您的两个代码示例中,两个版本的编译代码很可能是相同的。
我定义了两个简单的 classes Test1
和 Test2
并编译了它们。
public class Test1{
public String f(){
String s = "Hello";
String t = "There";
return s + t;
}
}
和
public class Test2{
public String f(){
return "Hello" + "There";
}
}
令我惊讶的是,.class 文件的大小不同。
-rw-r--r-- 1 csckzp staff 426 Dec 23 19:43 Test1.class
-rw-r--r-- 1 csckzp staff 268 Dec 23 19:43 Test2.class
也许我不应该感到惊讶,因为一些符号信息与代码一起存储。我通过在线反编译器 运行 .class 文件。 Test1
几乎按照输入的方式重建。Test2
,另一方面,以这种方式反编译:
public class Test2 {
public String f() {
return "HelloThere";
}
}
编译器的优化在这里一目了然。对于非紧凑代码,Java 中可能有一个小惩罚。
虽然局部变量在转换为字节码后仍然存在,但它们不太可能在即时编译中存在。此外,即使存在局部变量,它们也不会显着影响该方法的性能,因为重新缩放位图比存储或检索局部变量要昂贵几个数量级。
关于字符串连接的第二个示例突出了此规则的一个小例外,因为局部变量的存在可能会抑制常量字符串连接的编译时评估。然而,这不太可能显着影响程序的运行时间,因为您可能不会经常连接常量字符串。
一般来说,内联局部变量对运行时性能的影响很少可衡量,更不用说显着了。因此,您的时间最好花在优化程序员的性能上,让您的代码易于阅读和推理。
我做了一些研究,但我主要看到的是 C++ 答案。我最接近的是 this. I also saw this page 但它并没有真正解释任何东西。
如果我使用第二段代码有什么优势吗?会有明显的性能差异吗?内存呢?如果重复做怎么办?
现在我有这个功能。我确信这样做的好处是代码可读性:
private static Bitmap resize(Bitmap image, int maxWidth) {
float widthReducePercentage = ((float) maxWidth / image.getWidth());
int scaledHeight = Math.round(image.getHeight() * widthReducePercentage);
return Bitmap.createScaledBitmap(image, maxWidth, scaledHeight, true);
}
现在,我有了第二段代码:
private static Bitmap resize(Bitmap image, int maxWidth) {
return Bitmap.createScaledBitmap(image, maxWidth, Math.round(image.getHeight() * (float) maxWidth / image.getWidth()), true);
}
一个更简单的例子是:
for(;;) {
String foo = "hello";
Console.print(foo + "world");
}
对比
for(;;) {
Console.print("hello" + "world");
}
他们都是一样的。前者只是比后者更清楚。
在某些情况下,例如下面的块,单行代码很有用。
public boolean isEmpty() {
return getCount() != 0;
}
如果您想让它更易于阅读,尤其是涉及方程式时,请选择 variable
。一行使其简单和简短,但有利于简短和简单的逻辑。
这是我个人的看法。
首先:这不是"inlining"的意思。参见:What is inlining?
其次:不,性能不会有任何可衡量的差异。在您的两个代码示例中,两个版本的编译代码很可能是相同的。
我定义了两个简单的 classes Test1
和 Test2
并编译了它们。
public class Test1{
public String f(){
String s = "Hello";
String t = "There";
return s + t;
}
}
和
public class Test2{
public String f(){
return "Hello" + "There";
}
}
令我惊讶的是,.class 文件的大小不同。
-rw-r--r-- 1 csckzp staff 426 Dec 23 19:43 Test1.class
-rw-r--r-- 1 csckzp staff 268 Dec 23 19:43 Test2.class
也许我不应该感到惊讶,因为一些符号信息与代码一起存储。我通过在线反编译器 运行 .class 文件。 Test1
几乎按照输入的方式重建。Test2
,另一方面,以这种方式反编译:
public class Test2 {
public String f() {
return "HelloThere";
}
}
编译器的优化在这里一目了然。对于非紧凑代码,Java 中可能有一个小惩罚。
虽然局部变量在转换为字节码后仍然存在,但它们不太可能在即时编译中存在。此外,即使存在局部变量,它们也不会显着影响该方法的性能,因为重新缩放位图比存储或检索局部变量要昂贵几个数量级。
关于字符串连接的第二个示例突出了此规则的一个小例外,因为局部变量的存在可能会抑制常量字符串连接的编译时评估。然而,这不太可能显着影响程序的运行时间,因为您可能不会经常连接常量字符串。
一般来说,内联局部变量对运行时性能的影响很少可衡量,更不用说显着了。因此,您的时间最好花在优化程序员的性能上,让您的代码易于阅读和推理。