| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> Lambda表达式为什么运行效率低 -> 正文阅读 |
|
[大数据]Lambda表达式为什么运行效率低 |
目录 准备:我为什么说Lambda表达式运行效率低. 先准备一个list:
先用Lambda表达式的方式来循环一下这个list:
运行时间大概为110ms 再用普通方式来循环一下这个list:
运行时间大概为0ms或1ms 大家看到了吧,运行时间差距就是这么大,不信大家可以试试,并且不是只有在循环的时候Lambda表达式才会导致运行效率低,而是Lambda表达式在运行的时候需要额外的时间,我们继续分析。 分析如果我们有研究Lambda表达式,最正确,最直接的方法就是查看他所对应的字节码指令。 使用以下命令查看class文件对应的字节码指令:
上述命令解析出来的指令很多,我这里提取比较重要的部分来给大家分析: 使用Lambda表达式所对应的字节码指令如下:
不使用Lambda表达式所对应的字节码指令如下:
从上面两种方式所对应的字节码指令·可以看出,两种方式的执行方式确实不太一样。 不使用Lambda表达式执行流程字节码指令执行步骤:
那么这个流程大家应该问题不大,是一个正常的循环逻辑. 使用Lambda表达式执行循环流程字节码指令执行步骤:
?和上面正常循环的方式的字节码指令不太一样,我们认真的看一下这个字节码指令,这个流程并不像是一个循环的流程,而是一个方法顺序执行的流程: 先初始化一些数据 所以呀,Lambda表达式循环时,再循环前会做一些事情,所以导致执行时间要更长一些: 那么invokedynamic指令到底做什么事情? List.forEach方法接受一个参数,Consumer<? super T> action,Consumer是个接口,所以如果要调用此方法,就要传递该接口类型的对象。 代码里实际传递的是Lambda表达式,那么我们这里可以假设,需要将Lambda表达式转换为对象,对象的类型需要根据Lambda表达式所使用的地方在编译时期进行反推。
那么如果将Lambda表达式转换为一个对象,就需要实现Consumer接口。 问题就是这类什么时候生成的,并且声称在哪里? 我们应该想到,invokedynamic指令,他是不是先将Lambda表达式转换为某个类,然后生成一个实例以便forEach调用? 指令如下:
java中调用函数有四大指令:invokevirtual,invokespecial,invokestatic,invokeinterface,在JSR 292添加一个新的指令invokedynamic,这个指令表示执行动态语言,也就是Lambda表达式. 该指令注释中的#0表示的是BootstrapMethods中第0个方法:
所以invokedynamic方法执行时,实际上就是执行BootstrapMethods方法,java/lang/invoke/LambdaMetafactory.metafactory 代码如下:
此方法用到一个特别明显且易懂得类:InnerClassLambdaMetafactory. 这类是一个针对Lambda表达式生成内部类的工厂类,调用buildCallSite()方法会生成一个内部类以及所属实例。 那么现在生成一个内部类,需要一些什么条件呢: 类名:可按一些规则生成 类需要实现的接口:编译时就已知了,本例中就是Consumer接口 实现接口里面的方法:本例中Consumer接口的void accept(T t )方法. 如何实现void accept(T t )方法呢? 在javap -v -p Test.class 的结果另外的方法:
很明显,这个静态的lambda$main$0方法代表的就是我们写的lambda表达式,只是因为我们离子中的lambda表达式没写逻辑,所以这段字节码指令部分没什么内容。 那么我们在实现内部类的void accept(T t )方法时,只要调用一个这个lambda$main$0静态方法即可。 所以到此,一个内部类就可以被正常的实现出来了,内部类有了之后,Lambda表达式就是可以被转换成这个类的内部类对象,就可以进行循环了。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 13:24:44- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |