一直都说php比java要慢,今天从理论跟实际测试看看php是否真的慢,慢在哪里

一: 运行模式对比

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执行流程请参考:PHP执行流程简述

三:语言特性

从整个语言编译执行流程上来看,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毫秒比确实也还有差距

总结:PHP 不管是从执行模式,编译流程,还是从语言执行效率上来说都不比java快,但是通过相应的优化后 PHP也并没有网上说的那么大差距,尤其是现在Web 编程以IO为主要约束的时代,基本上PHP可以做到跟java 媲美的效率,另外PHP 在模块拆分,热更新等项目管理上有得天独到的优势,所以是用java还是PHP得自己根据项目需求理解选择

下面是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执行流程请参考:PHP执行流程简述

参考文章:https://blog.csdn.net/qq_40488936/article/details/106308182
https://blog.csdn.net/weixin_43814458/article/details/106405207

Java为啥比PHP快?相关推荐

  1. Python到底是什么样的语言? Python和Java比谁更快? TensorFlow的主体是用Python写的吗?

    Python到底是什么样的语言? Python和Java比谁更快? TensorFlow的主体是用Python写的吗? Python到底是什么样的语言? 解析: 这里是一些关键点:Python是解释型 ...

  2. Vite为啥如此之快

    文章目录 1. Vite为啥比Webpack快 1.1 快速的冷启动 Webpack为什么慢 Vite为什么快 1.2 快速的热更新 Wabpack Vite 2. Vite的缺点 首屏 懒加载 1. ...

  3. java 滚动加载数据_[Java教程]浏览器滚动条快到底部时自动加载数据

    [Java教程]浏览器滚动条快到底部时自动加载数据 0 2015-11-30 15:00:44 1 2 3 4 5 6 ");24 main.append(" hello worl ...

  4. 吊打 ThreadLocal,谈谈FastThreadLocal为啥能这么快?

    欢迎关注方志朋的博客,回复"666"获面试宝典 1 FastThreadLocal的引入背景和原理简介 既然jdk已经有ThreadLocal,为何netty还要自己造个FastT ...

  5. Java: 复制文件最快、高效率的方法

    Android中的文件复制--视频和图片复制 public class FileOpreateUtils {/*** * @param fromFile 被复制的文件* @param toFile 复 ...

  6. Java 8中最快的垃圾收集器是什么?

    OpenJDK 8具有几种垃圾收集器算法,例如Parallel GC , CMS和G1 . 哪一个最快? 如果默认的GC从Java 8中的并行GC更改为Java 9中的G1(当前建议),将会发生什么? ...

  7. 这样学习JAVA 基础才能又快又稳!

    微服务架构 企业和服务提供商正在寻找更好的方法将应用程序部署在云环境中,微服务被认为是未 来的方向.通过将应用和服务分解成更小的.松散耦合的组件,它们可以更加容易升级和扩展. 目前, 越来越流行的微服 ...

  8. java 快速io_java 最快的input (ACM) Java高效IO

    java 最快的input 问题: Scanner 非常非常非常慢 使用Scanner来输入非常方便,但很慢. 使用 BufferedReader 和 StringTokenizer 会更快, 但是在 ...

  9. 听说Java老古董了?快被淘汰了?高级开发:我还就真看上它了!

    听过Java快被淘汰了?没那么容易! Java从诞生至今,已经走过了20多年的历史,虽然相比新型的技术语言算是"老古董",但是它的应用依然最为广泛,并且有着非常成熟的生态. 编程圈 ...

最新文章

  1. 在SharePoint Foundation 2010中显示来自其他站点的列表
  2. Android实用代码七段(五)
  3. python库下载安装网址
  4. mysql主从切换机制torch_Mysql主从复制 - osc_y0vjyklt的个人空间 - OSCHINA - 中文开源技术交流社区...
  5. tomcat和resin的安装配置
  6. javascript标签在页面中的位置探讨
  7. linux path在哪个文件夹,linux PATH环境变量全解析
  8. 求和第一个算到最后一个周末求_Excel最全求和函数—sum家族系列
  9. 便携式三星mysql_JDBC链接mysql - 三星蓝
  10. sap中泰国有预扣税设置吗_泰国的绘图标志| Python中的图像处理
  11. install mysql 5.6.22 source code
  12. Java 数组类型转字符串类型
  13. DOC命令小问题~~+理解
  14. 回归分析beta值的标准_Beta值的基本原理及使用说明
  15. python socket和多线程实现多人对话聊天室
  16. Djano之写api使用django_rest_framework【海瑞博客】
  17. fluent udf dpm 捕集效率
  18. UE4使用贴花(Decal)
  19. openlayers地图初始化
  20. 六脚自锁开关引脚图及功能定义

热门文章

  1. 怎么将PDF转成Word
  2. d58站群inc.php,D58站群2018年版本SEO特殊字符静态文件生成根目录源码分享
  3. 安装node npm
  4. 解读spy++,鼠标按下雷电模拟器,产生的一系列Windows Message消息队列解读
  5. [论文写作笔记] C3 让题目闪光
  6. 北京短视频运营哪里能学到
  7. windows10系统如何实现二分屏、三分屏和四分屏
  8. node爬虫快速入门
  9. 【已解决】群晖套件中心无法添加第三方源 6.23
  10. HTTPS加密过程和TLS证书验证