java 真的比php快吗,快又快在哪里,php有优化的方案吗?,php 8.0 jit有实际意义吗?
java:一般用java 语言开发的网站项目都是以命令行模式运行,部分可能以可执行文件(.exe)的形式运行; php:主要以cgi模式运行,部分以cli模式运行,如swoole 拓展; php cgi 模式下每次请求进来都需要以进程的方式执行php代码,创建进程以及进程切换都需要消耗不少资源; 优化方案:1:FPM 进程池保持一定活跃进程,做到进程重用 2:使用swoole 拓展,将php以cli模式执行,这模式上就跟java类似了;
java:执行前需要编译为jvm的字节码(不是cpu的字节码),代码执行直接解析字节码或者将字节码编译为机器二进制码后执行 php:每次请求进来都需要经过代码分析->解析->编译opcode->执行的流程,前面3步比起java都是额外的损耗 优化方案:php开启opcache缓存(5.5以后官方自带拓展),可以省去前面3步的重复工作; php执行流程请参考:<a href="https://blog.csdn.net/lqb3732842/article/details/122171943">PHP执行流程简述</a>
从整个语言编译执行流程上来看,php经过上面的优化效率应该跟java不相上下才对,下面单从语言上对php 跟java做一次测试;
测试环境:Windows 10 64位 cpu i5 内存8g java版本:jdk 10 php版本:php 8.0.14 测试功能:用两种语言实现相同数据量(2w个整数)的冒泡排序,对比双方执行时间;
代码如下:
java 代码
public class Test {
public static void main(String[] args) {
long st=System.currentTimeMillis();
int count=20000;//这个数考虑到php 执行时间,选取了这个,越大对java 越有利
int[] arr=new int[count];
//数组赋值随机数
for (int i=0;i<count;i++){
final double d = Math.random();
arr[i] = (int)(d*count);
}
System.out.println("数据生成用时="+(System.currentTimeMillis()-st));
for(int i=0;i<arr.length-1;i++){
for(int j=0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println("总共耗时="+(System.currentTimeMillis()-st));
}
}
php 代码
<?php
/**
* Created by PhpStorm.
* User: 05
* Date: 2021/12/27
* Time: 10:50
*/
class Test
{
public function msort(){
$arr=[];
$count=20000;//这个数据大了 要运行很久,经过多测测试 2w比较合适
$st=microtime(true);
//生成随机数赋值
for ($i=0;$i<$count;$i++){
$arr[$i]=mt_rand(0,$count);
}
echo "数据生成用时=".(microtime(true)-$st);
for ($i=0;$i<$count-1;$i++){
for ($j=0;$j<$count-1-$i;$j++){
if ($arr[$j]>$arr[$j+1]){
$temp=$arr[$j];
$arr[$j]=$arr[$j+1];
$arr[$j+1]=$temp;
}
}
}
echo "总用时=".(microtime(true)-$st);
}
}
$t=new Test();
$t->msort();
结果
java:随机产生2w个整数耗时需要3毫秒,生成数据到排序完2w个数排序需要800毫秒左右,这里测试了多次,时间相差不大 PHP:未开启opcache 跟 jit 生成随机数 耗时:1毫秒多点,完成整个排序耗时:13秒多… 这个结果还是让我大跌眼镜,因为这个代码只是测试 php跟 java的执行效率,php也就编译一次,但是整个效率相差十几倍…
结论: 从上面的分析java 跟php的整个编译执行流程应该是差不多的,这里php 也没有多次的编译,所以只能是php 的ZendVM 虚拟机执行opcode的效率不如 JVM的执行字节码的效率,大概原因是 php是弱类型语言,每次执行opcode 时还需要对变量类型进行判断,无法做到强类型语言那样精确的指令转换 ,但是PHP 8.0后也使用了JIT 及时编译技术;
下面我们打开PHP的JIT 在进行测试一次 结果:总耗时为3秒多,比一开始的13秒确实是质的提升,但跟java 的800毫秒比确实也还有差距
下面是JVM 虚拟机执行,引用网上总结
Java 虚拟机的运行效率如何? HotSpot 采用了多种技术来提升启动i性能以及峰值性能,即时编译就是其中最重要的技术之一。即时编译建立再程序符合二八定律的假设,即百分之二十的代码占据了百分之八十的计算资源。 对于占据大部分的不常用的diamagnetic,我们无需耗时将其编译成机器码,而是采取解释执行的方法运行,另一方面,对于仅占小部分的热点代码,可以将其编译成机器码,已达到理想的运行速度。 理论上讲,即使编译后的 Java 程序的执行效率是可能超过 C++ 程序的。这是因为与静态编译相比,即时编译用程序的运行时信息,并且能够根据这个信息做出相应的优化。例如我们知道虚方法是用来实现面向对象多态性的。对于一个虚方法调用,尽管它由多个目标方法,但在实际运行中它可能只调用其中的一个。这个信息便可以被即时编译器所利用,来规避虚方法调用的开销,从而达到比静态编译的 C++ 程序更高的性能。 为了满足不同场景的需要,HotSpot 内置了多个即时编译器:C1,C2 和 Graal…至多一引入多个即时编译器,是为了在编译时间和生成代码的执行效率之间进行取舍。C1有叫做 Client 编译器,面向的是对启动性能有要求的客户端 GUI 程序,采用的优化手段相对简单,因此编译时间较短。C2 又叫做 Server 编译器,面向的是对峰值性能又要求的服务器程序,采用的优化手段相对复杂,因此编译时间比较长,但同时生成diamagnetic的执行效率较高。 Java 7 以后,HotSpot 默认采用分层编译的方法:热点方法会首先被 C1 编译,而后热点方法中的热点会进一步被 C2 编译。为了不干扰应用的正常运行,HotSpot 的即时编译是放在额外的编译线程中进行的。HotSpot 会根据 CPU 的数量设置编译线程的数目,并且按 1:2 的比例配置给 C1 及 C2 编译器。 在计算资源充足的情况下,字节码的解释执行和即时编译可同时进行。编译完成后的机器码会在下次调用该方法时启动,以替换原本的解释执行。
php执行流程请参考:<a href="https://blog.csdn.net/lqb3732842/article/details/122171943">PHP执行流程简述</a>
参考文章:https://blog.csdn.net/qq_40488936/article/details/106308182 https://blog.csdn.net/weixin_43814458/article/details/106405207
本站为非盈利网站,如果您喜欢这篇文章,欢迎支持我们继续运营!
本站主要用于日常笔记的记录和生活日志。本站不保证所有内容信息可靠!(大多数文章属于搬运!)如有版权问题,请联系我立即删除:“abcdsjx@126.com”。
QQ: 1164453243
邮箱: abcdsjx@126.com