java - 使用lambda表达式(匿名内部类)传参是否有性能问题?
阿神
阿神 2017-04-18 10:53:20
0
3
1098

编程有一条原则如下:

避免创建不必要的对象:最好能重用对象,而不要在每次需要的时候就创建一个相同功能的新对象。

请看如下代码:

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");

 // 1、匿名内部类
Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return b.compareTo(a);
    }
});

//2、lambda表达式
Collections.sort(names, (a, b) -> b.compareTo(a));

是不是每次排序都创建了一个新的Comparator对象,导致性能降低?那么还主张使用Lambda表达式吗

阿神
阿神

闭关修行中......

reply all(3)
Peter_Zhu

First answer your question:
Is a new Comparator object created every time sorting, resulting in reduced performance? So do you still advocate using Lambda expressions?
No, claim

  1. The fundamental reason
    Lamdba expression is not syntactic sugar for anonymous inner classes at all. That is to say, the underlying implementation of Lambda expression is not the implementation of anonymous inner classes. They are actually two things

  2. How to prove it?
    Anonymous inner classes will actually generate a class file during compilation, named with ClassName$ numbers, so if the bottom layer of the Lamdba expression is also implemented by anonymous inner classes, a similarly similar inner file will definitely be generated.
    So we simply write your example in classes under different packages, and then check the compiled effect
    Anonymous inner class implements InnerTest


    This is a class file, you can see there are two

    lambda expression LamdbaTest

    However, there is only one class file


    So there is only one truth, haha, obviously, this is not the same thing at all

  3. How is Lamdba expression implemented?
    We can take a look at their bytecode, so that the underlying differences will be fully demonstrated
    InnerTest

    LamdbaTest

    You can see that the instructions used by the two are different. When parsing the Lamdba expression, it uses the new invokedynamic instruction in Java 7. If you are familiar with this instruction, you may understand it instantly. If you are not familiar with it, you may understand it instantly. , you can ask Du Niang
    But you can understand it directly from the name of this command: Dynamic call
    Therefore, unlike anonymous inner classes that are compiled into a class file, Lamdba expressions are compiled into a static method , we can see it again by looking at -p. The generated method is called lambda$main

    🎜
所以结合之前两个反编译的结果可以看到,lamdba表达式运行整体思路大致如下  
    1. lamdba表达式被编译生成当前类的一个私有静态方法  
    2. 在原调用Lamdba方法的地方编译成了一个invokedynamic指令调用,同时呢也生成了一个对应的BootstrapMethod  
    3. 当lamdba表达式被JVM执行,也就是碰到2中说到的invokedynamic指令,该指令引导调用LambdaMetafactory.metafactory方法,该方法返回一个CallSite实例
    4. 而这个CallSite实例中的target对象,也就是直接引用到一个MethodHandle实例,而这个MethodHandle实例会调用到1中生成的静态方法,在上面的例子就是`lambda$mainrrreee`这个方法,完成整个lamdba表达式的使用  
  1. One more thing
    In fact, you can see that lamdba expressions are indeed much better than anonymous inner classes in a sense, whether it is performance, readability or general trend~ Haha, I want to say general trend because lamdba expressions can be used later There is wider room for optimization. Anyway, I am used to using it in java and I like it very much

阿神
  1. Each sorting does not create a new Comparator object. Generally, once the instance corresponding to the Lambda expression is generated in memory, the JVM will reuse this instance in the current environment. For specific instructions, you can refer to this link: Run-Time Evaluation of Lambda Expressions

  2. On the premise that it can improve program readability and development efficiency, it is recommended to use Lambda expression

刘奇
  1. You can statically declare an anonymous class object inside a Lambda expression;

  2. Small objects that come and go are not a big problem for the JVM;

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!