Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 隐式(自动)取消装箱还是显式取消装箱,哪种性能更好?_Java_Performance_Unboxing - Fatal编程技术网

Java 隐式(自动)取消装箱还是显式取消装箱,哪种性能更好?

Java 隐式(自动)取消装箱还是显式取消装箱,哪种性能更好?,java,performance,unboxing,Java,Performance,Unboxing,把它放在代码中——哪一个性能更好(如果有区别的话) 鉴于此: public class Customer { .... public Boolean isVIP(){...} ... } 哪个更快 public void handleCustomer(Customer customer) { if (customer.isVIP()) // Auto Unboxing { handleNow(customer); }

把它放在代码中——哪一个性能更好(如果有区别的话)

鉴于此:

public class Customer
{
    ....

    public Boolean isVIP(){...}
    ...
}
哪个更快

public void handleCustomer(Customer customer)
{
    if (customer.isVIP())  // Auto Unboxing
    {
        handleNow(customer);
    }
    else
    {  
        sayHandlingNowButQueueForTomorrow(customer);
    }
}
或者这个:

public void handleCustomer(Customer customer)
{
    if (customer.isVIP().booleanValue()) // Explicit unboxing
    {
        handleNow(customer);
    }
    else
    {  
        sayHandlingNowButQueueForTomorrow(customer);
    }
}

差异应该都在编译时出现,因为自动取消装箱只是语法上的糖分。在这种情况下,生成的Java字节码应该完全相同。这意味着在运行时没有区别。但是,在更一般的情况下,显式取消装箱可能会更快,因为隐式取消装箱可能会多次取消装箱值,而使用显式取消装箱,您可以保证只取消装箱一次并存储结果。

差异应该都在编译时出现,因为自动取消装箱只是语法上的糖分。在这种情况下,生成的Java字节码应该完全相同。这意味着在运行时没有区别。但是,在更一般的情况下,显式取消装箱可能会更快,因为隐式取消装箱可能会多次取消装箱值,而使用显式取消装箱可以保证只取消装箱一次,并存储结果。

从性能角度看,理想情况下,它们应该是相同的

有一种可能性是,人工编写的技术有点不太理想,因此,如果您使用糟糕的人工编写的自动装箱方法,可能会影响性能。但是,如果您真的想实现它,那么人类编写某种非通用解决方案的可能性是相同的,这种非通用解决方案优于默认性能。这样的解决方案不会那么灵活,它可能会在计算复杂性和内存之间进行权衡(比如一个大的查找数组)

就我个人而言,我建议花一些时间来真正地了解更大的情况。优化一两行代码几乎从来都不是一项好的投资。减少整个项目所需的工作量更有可能提高绩效

注意,在一般情况下,JVM并没有随着自动装箱的引入而改变,只是编译器改变了。因此,编译器添加的指令与在最常见的情况下手动编写的指令相同。性能是在运行时在JVM中测量的,如果两种方式的字节码都相同,那么就没有理由期望性能有差异


这有点过早优化的味道,但是如果你认为你可以在时间上找到差异:通过仔细的测试来做到这一点,然后意识到在不同的点版本、操作系统等上可能会有所不同。在任何情况下,这都不是一个明确的胜利。

就性能而言,理想情况下它们应该是相同的

有一种可能性是,人工编写的技术有点不太理想,因此,如果您使用糟糕的人工编写的自动装箱方法,可能会影响性能。但是,如果您真的想实现它,那么人类编写某种非通用解决方案的可能性是相同的,这种非通用解决方案优于默认性能。这样的解决方案不会那么灵活,它可能会在计算复杂性和内存之间进行权衡(比如一个大的查找数组)

就我个人而言,我建议花一些时间来真正地了解更大的情况。优化一两行代码几乎从来都不是一项好的投资。减少整个项目所需的工作量更有可能提高绩效

注意,在一般情况下,JVM并没有随着自动装箱的引入而改变,只是编译器改变了。因此,编译器添加的指令与在最常见的情况下手动编写的指令相同。性能是在运行时在JVM中测量的,如果两种方式的字节码都相同,那么就没有理由期望性能有差异


这有点过早优化的味道,但如果你认为你能在时间上找到差异:通过仔细的测试,然后意识到在不同的点版本、操作系统等上可能会有所不同。无论如何,这都不是一个明确的胜利。

它们之间没有区别,你可以在字节码中验证:

public class ImplicitTest {
    public static void main(String[] args) {
        Boolean b = true; 
        boolean i = b;
        boolean e = b.booleanValue();
    }
}
运行以查看它编译为什么:

javap -c ImplicitTest
以下是输出:

Compiled from "ImplicitTest.java"
public class ImplicitTest extends java.lang.Object{
public ImplicitTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   invokestatic    #2; //Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
   4:   astore_1
   5:   aload_1
   6:   invokevirtual   #3; //Method java/lang/Boolean.booleanValue:()Z
   9:   istore_2
   10:  aload_1
   11:  invokevirtual   #3; //Method java/lang/Boolean.booleanValue:()Z
   14:  istore_3
   15:  return

}
从“ImplicitTest.java”编译而来
公共类隐式测试扩展了java.lang.Object{
公共隐式测试();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:iconst_1
1:invokestatic#2;//方法java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4:astore_1
5:aload_1
6:invokevirtual#3;//方法java/lang/Boolean.booleanValue:()Z
9:istore_2
10:aload_1
11:invokevirtual#3;//方法java/lang/Boolean.booleanValue:()Z
14:istore_3
15:返回
}

如您所见-第5、6、9行(隐式)与第10、11、14行(显式)相同。

它们之间没有区别,您可以在字节码中验证:

public class ImplicitTest {
    public static void main(String[] args) {
        Boolean b = true; 
        boolean i = b;
        boolean e = b.booleanValue();
    }
}
运行以查看它编译为什么:

javap -c ImplicitTest
以下是输出:

Compiled from "ImplicitTest.java"
public class ImplicitTest extends java.lang.Object{
public ImplicitTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_1
   1:   invokestatic    #2; //Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
   4:   astore_1
   5:   aload_1
   6:   invokevirtual   #3; //Method java/lang/Boolean.booleanValue:()Z
   9:   istore_2
   10:  aload_1
   11:  invokevirtual   #3; //Method java/lang/Boolean.booleanValue:()Z
   14:  istore_3
   15:  return

}
从“ImplicitTest.java”编译而来
公共类隐式测试扩展了java.lang.Object{
公共隐式测试();
代码:
0:aload_0
1:invokespecial#1;//方法java/lang/Object。“:()V
4:返回
公共静态void main(java.lang.String[]);
代码:
0:iconst_1
1:invokestatic#2;//方法java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
4:astore_1
5:aload_1
6:invokevirtual#3;//方法java/lang/Boolean.booleanValue:()Z
9:istore_2
10:aload_1
11:invokevirtual#3;//方法java/lang/Boolean.booleanValue:()Z
14:istore_3
15:返回
}

如您所见,第5、6、9行(隐式)与第10、11、14行(显式)相同。

是一个VIP,因此它必须返回
布尔
而不是
布尔

是一个VIP,因此它必须返回
布尔
而不是
布尔
我认为您有“隐式”的含义反向-如果调用
.booleanValue()
方法取消对值的装箱