• JSP,PHP详细性能测试


    前几天在CU看到有人比较PHP与JSP,.net,结果表明PHP比JSP,.net性能低下很多。本人认为即使有差距,也不应该有这么大,所以认真测试一下几者间的性能差距。由于很久没用.net了,所以,暂时没有测试.net。

    本测试数据真实,但只做为参考。欢迎大家讨论。
    除做比较外,也可供PHP,JSP程序员参考,以便优化自己的程序。

    本测试由一直漂(ipaddr,bcomcn)原创,欢迎转载,并注明出处。问题反馈:admin.net(at)163.com

    测试环境:
    硬件:P4 2.4G,1G内存 软件:WindowsXP+Apache2.0.54+PHP4.4.0+Mysql4.1.14+Tomcat5.0.28
    讨论地址:http://bbs.chinaunix.net/viewthread.php?tid=641073

    一.算术运算

    a.测试标准

    循环N次,并做整型自加运算。

    b.测试

    测试代码:

    测试类型 JSP int整型 JSP long整型 JSP long整型2 PHP PHP2
    测试代码 int i=0;
    while (i<XXXX)
    {
    i++;
    }
    long l=0;
    while (l<XXXX)
    {
    l++;
    }
    long l=0;
    while (l<XXXX)
    {
    l=l+1;
    }
    $i=0;
    while ($i<XXXX)
    {
    $i++;
    }
    $i=0;
    while ($i<XXXX)
    {
    $i=$i+1;
    }

    测试结果(单位:毫秒)

    测试结果说明:m-n表示主要波动范围介于m和n之间;n表示出现次数非常之多的数值或平均值,m(x,y)表示偶尔会出现x,y。以下相同。

    XXXX取值 JSP int整型 JSPlong整型 JSPlong整型2 PHP PHP2
    1000 0 0 0 0-1 0-1
    10000 0 0 0 3-4 6-7
    100000 0 0 0(16,32) 34-35 51-52
    1000000 0(10) 0(16,32) 0(16,32) 348-368 527-534
    10000000 0(13) 16-32 32-78 3547-3585 5239-5390
    100000000 0(16) 266-281 265-281 35309-35486  
    1000000000 0(16,743) 2625-2676 2203-3687    

    c.结论

    Java的算术运算,优化得很好,估计是直接的对应CPU的指令,数值再大,算术运算性能都很平稳。
    需要注意的是,long的运算时间要比int的运算时间要长一些(毕竟是32位的系统),所以,在无需用到long时,尽量不要用long,而用int.

    PHP是弱类型的变量,算术运算很不尽人意,估计不是直接对应机器码的算术运算。
    PHP算术运算的过程猜测如下,在运算前需要检测变量是否是数值,并要将非数值转换成数值,比如,PHP可以做这样的运算:100+"zhoutang",结果等于100.正是因为是弱类型语言,加上运算前的检测和转换,所以才导致算术运算的性能低下。
    PHP的单次运算时间比较稳定,大概每10000次算术加运算花费的时间约为3.5ms

    不同的运算方法,也对性能有影响。

    二.字符串运算

    a.测试标准

    字符串连接运算对比。

    b.测试

    测试代码:

    测试类型 JSP PHP
    测试代码 String str="";
    while (str.length()< XXXX)
    {
    str+="a";
    }
    $str="";
    while (strlen($str)< XXXX)
    {
    $str.="a";
    }

    测试结果(单位:毫秒)

    XXXX取值 JSP PHP
    1000 0-16 1
    10000 656-703 9-10
    100000 105078-105235 95-103

    c.结论

    Java的字符串是用对象处理,很明显,在字符串的比较过程中,Java比PHP差很远。(因为字符串操作,很大部分要做连接,这里只比较连接运算,另外粗略比较了一下substring,两者的差别不是很大)

    PHP的字符串运算,估计很多是直接调用C的字符串函数,所以效率会高很多。

    在做WEB开发中,字符串的连接操作还是很频繁的(包括很多时候生成SQL字符串),所以,在算术运算和字符串运算两个方面,Java(JSP)优势不明显,与PHP各有所长。

    三.数据库查询

    a.测试标准

    循环N次做数据库打开,查询,关闭操作。主要对JSP直接连数据库,JSP连接池连数据训,PHP直接连数据库,PHP持久连数据库做比较。

    b.测试结果

    测试代码:

    测试类型 测试代码
    JSP String dbUrl,dbUser,dbPwd,strSQL;
    dbUrl="jdbc:mysql://localhost:3306/zhoutang";
    dbUser="root";
    dbPwd="";
    strSQL="update tblUser set UserLC=UserLC+1 where UserID=100";

    Class.forName("com.mysql.jdbc.Driver");
    Connection con;
    Statement stmt;

    int i=0;
    while (i<XXX)
    {
    con=DriverManager.getConnection(dbUrl,dbUser,dbPwd);
    stmt=con.createStatement();
    stmt.executeUpdate(strSQL);
    stmt.close();
    con.close();
    stmt=null;
    con=null;
    i++;
    }

    JSP连接池 Context ctx=new InitialContext();
    DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/mysql");

    String strSQL="update tblUser set UserLC=UserLC+1 where UserID=100";

    Connection con;
    Statement stmt;

    int i=0;
    while (i<XXXX)
    {
    con=ds.getConnection();
    stmt=con.createStatement();
    stmt.executeUpdate(strSQL);
    stmt.close();
    con.close();
    stmt=null;
    con=null;
    i++;
    }

    PHP $dbHost="localhost";
    $dbUser="root";
    $dbPwd="";
    $dbName="zhoutang";
    $strSQL="update tblUser set UserLC=UserLC+1 where UserID=100";

    $i=0;
    while ($i< XXXX)
    {
    $link = mysql_connect($dbHost, $dbUser, $dbPwd)
        or die('Could not connect: ' . mysql_error());
    mysql_select_db($dbName);
    mysql_query($strSQL);
    mysql_close($link);
    $i++;
    }

    PHP持久连接 $dbHost="localhost";
    $dbUser="root";
    $dbPwd="";
    $dbName="zhoutang";
    $strSQL="update tblUser set UserLC=UserLC+1 where UserID=100";

    $i=0;
    while ($i< XXXX)
    {
    $link = mysql_pconnect($dbHost, $dbUser, $dbPwd)
        or die('Could not connect: ' . mysql_error());
    mysql_select_db($dbName);
    mysql_query($strSQL);
    mysql_close($link);
    $i++;
    }

    测试结果(单位:毫秒)

    XXXX取值 JSP JSP连接池 PHP PHP持久连接
    50 437-600 31-50 219-232 34-37
    100 890-1047 62-94 448-468 69-73
    200 2141-2263 157-189 948-979 159-175
    500 5078-5140 375 2118-2221 358-379

    c.结论

    普通连接,Java连Mysql的速度是要比PHP慢的一倍左右。Java使用连接池技术,性能提升非常明显。

    PHP使用的持久连接(pconnect)性能即然相当于Java的连接池,结果实在让人不可思议,本来挺担心PHP连数据库的,因为没连接池可 用,特意在网上找了一些资料,没发现PHP可用的连接池,相关提法都很少,很多PHP程序员甚至没听过这概念,这样的结果,确实让我也大吃一惊。不过,话 说回来,pconnect的原理,和连接池差不多的,都是程序关闭连接,但PHP并不真正关闭,再次打开时,直接使用可用的连接。但是,PHP的实现确实 比Java方便多了,只需加个字母,就轻易实现,Java则麻烦一些,我配置Tomcat的连接池都费了些时间,按官方文档,在tomcat5.0.28 下没配置成功,在CSDN上面,也看到很多新手发出求救,很多配置不成功的,最后自己摸索出来了,配置方法可参考我的Blog。

    如果将连接数据库和关闭数据库的操作,移到循环外面,刚PHP和JSP的执行时间都差不多,循环50次约16ms。可见,数据库操作中,打开连接是 相当耗资源的,其它操作,与语言差别不大。JSP在连接数据库的时候,开销比PHP大很多。(这里特意将打开数据库操作放在循环体做比较)

    四.文件操作

    在WEB开发过程上,文件操作一般不可缺少,大多数WEB系统都会上传或对文件操作。

    a.测试标准

    综合测试各种文件操作,测试的过程是首先判断某文件是否存在,存在的话删除文件,再新建文件,再往文件里写一定长度的内容。整个过程循环N次。

    b.测试结果

    测试代码:

    测试类型 测试代码
    JSP String fileName="jsp.txt";
    String filePath=request.getRealPath("");
    int i=0;
    int j=0;
    while (i<XXXX)
    {
    File f=new File(filePath,fileName);
    if(f.exists())
    {
    f.delete();
    }
    f.createNewFile();
    FileWriter fw=new FileWriter(filePath+File.separator+fileName);
    j=0;
    while (j<2*i)
    {
    fw.write(j+" ");
    j++;
    }
    fw.close();
    i++;
    }
    PHP $fileName="./php.txt";
    $i=0;
    while ($i<XXXX)
    {
    if (file_exists($fileName))
    {
    unlink($fileName);
    }
    $handle=fopen($fileName,"x");
    $j=0;
    while ($j<2*$i)
    {
    fwrite($handle,$j." ");
    $j++;
    }
    fclose($handle);
    $i++;
    }

    测试结果(单位:毫秒)

    XXXX取值 JSP PHP
    100 265-292(326,431) 346-367
    500 1703-2065 3256-3474
    1000 4062-4398 9316-9348

    c.结论

    这个测试结果有点意外,本以为PHP会大胜的项目,却让JSP遥遥领先,循环次数大的时候,PHP比JSP慢一倍。有点不可思议。

    五.总结

    总体来说,PHP与JSP在性能上,差别不了很远,各有优势。JSP虽是编译执行,但却要通过JVM,性能会有所下降。从功能上说,JSP的相对强 大一些,主要是因为有Java的支撑,在一些很大型的企业中,用JSP有优势(主要是有Java支撑),但一般的企业或一般的应用,PHP完全可以应付。 另外,PHP比JSP更容易上手。另外,个人说为,做同样的WEB系统,PHP相对JSP来说,复杂度可能会低一些(JSP所有的技术都用上的话,估计架 构环境,系统设计都够麻烦的,而且,Java体系各种技术和产品比较开放和松散,文档相对来说有点杂乱,至少我认为Tomcat的文档做得没有 Apache,PHP的好。)。

    PHP小巧而灵活,JSP就显得宠大,而且,概念众多,个人认为Java体系有故意夸大技术复杂度的嫌疑。

    此外,PHP还有Zend可用,本来想装上Zend再来测试一番的,这几天Zend的网站老是上不去。据有关测试表明,Zend能提升PHP的性能 大约100%左右。也有说30-40%的,也有说600%的。估计是算术运算能提升个档次,其它操作,最多提升30-40%左右。

    在整个测试过程中,每个取值我都会测多次,一般10s以下的运算,我至少测10次,10s以上的运算,至少测3次。PHP的测试结果都比较稳定,每 次测出的结果差别不是很大,从统计学的角度来说,方差比较小。JSP相对来说,偶尔会出现一些值,偏离平均值比较远,而且,由于需要编译的原因,首次执行 一般时间比较长(虽然从程序里显示的数值看不出首次执行的时间差距,但在程序开始执行前,编译需要点时间。编译后才开始执行,所以程序显示的结果看不出 来。),所以,JSP的测试,没取首次运行的结果。

    另外,在测试连接数据库的过程中,由于一时疏忽,忘了在循环体内i++,导致出现死循环。所以,也特意做了几个死循环测试。算术运算测试,JSP死 循环时,浏览器点了停止按钮,tomcat仍继续执行,CPU一直是100%,只有在任务管理器里停了tomcat,才得以停止死循环;PHP算术运算死 循环,由于php.ini里有设置程序执行的最长时间和最大内存,所以,死循环能够自动结束。数据库连接死循环,JSP在循环大概900多次后,出现异 常,报错,提示无法连接;PHP循环1500次后,仍然没有结束,只好在任务管理器里结束apache进程(我的php.ini设置PHP最长执行时间为 300秒)。

    六.其它环境简单测试

    以上数据只能做为参考,同样的程序,在其它配置的系统,我也做了简单的测试:

    I.p4 2.4G,512M DDR,Windows server2000的工作机

    (安装东西比较多,比较乱,运行一年多没重装,由于是工作机,所以操作系统对应用程序优化,而不是对后端服务优化;所测得的数据,比XP下测得的数据要大很多,比如PHP连接Mysql循环500次,大约需要16000ms。),粗略的测试的结果是:

    算术运算和字符串运算:算术运算,JSP领先很多,字符串运算,PHP领先很多,和测试机的结果一致。

    连接数据库:PHP与JSP连Mysql速度差距不大,PHP大概快20%左右,奇怪的是我用pconnect连与connect是一样的结果,未测试JSP的连接池。估计JSP用连接池会快很多。

    文件操作:PHP的文件操作比JSP性能高出约30%!与测试机的结果有点相差比较大,PHP领先。

    II.p4 2.66G,1G DDR,Linux服务器

    算术运算和字符串运算:和其它环境测试结果一致,JSP在算术运算时领先,PHP在字符串运算时领先很多很多。

    连接数据库:执行500次循环,PHP用connect连接,花费185ms,PHP使用pconnect连接,花费70ms;JSP未用连接池,花费2030ms。

    文件操作:JSP领先很多,1000次循环,JSP花费1500ms左右,PHP花费7000ms左右。

    III.总结

    不管什么平台系统,测试结果表明,JSP和PHP在做WEB开发时,性能差距不大,只能说各有所长,JSP在数据库操作以及字符串操作方面不如PHP,而PHP在文件操作及算术运算是,不及JSP。

    此外,同种语言,在不同的平台表现也不一样,根据我的测试结果表明,Linux下PHP,JSP的性能都要优于Windows的。

    七.运行时间的获取

    语言 如何获取运行时间
    JSP

    long timeStart=0;
    long timeEnd=0;
    timeStart=Calendar.getInstance().getTimeInMillis();

    //中间代码

    timeEnd=Calendar.getInstance().getTimeInMillis();
    out.println("开始时间:"+timeStart+"毫秒<br>");
    out.println("结束时间:"+timeEnd+"毫秒<br>");
    out.println("花费时间:"+(timeEnd-timeStart)+"毫秒<br>");

    PHP

    $timeStart=0;
    $timeEnd=0;
    $timeStart=mictime();

    //中间代码

    $timeEnd=mictime();
    echo "开始时间:".$timeStart."毫秒<br>";
    echo "结束时间:".$timeEnd."毫秒<br>";
    echo "花费时间:".($timeEnd-$timeStart)."毫秒<br>";

    function mictime()
    {
    //由于PHP支持不支持long型,所以,只取了5位秒数,再加上毫秒。时间段比较,前面的可以忽略
    list($usec, $sec) = explode(" ", microtime());
    $sec=substr($sec,-5);
    $usec=ceil($usec*1000);
    while (strlen($usec)<3)
    {
    $usec="0".$usec;
    }
    return $sec.$usec;
    }

    附不同框架测试对比:http://www.techempower.com/benchmarks/

  • 相关阅读:
    路由重分布(二)
    linux系统命令的收集 第一部分
    如何在VM软件中安装Linux系统
    Spring boot连接MongoDB集群
    jQuery中防止表单提交两次的方法
    Java中使用HTTP阻塞式调用服务器API
    本地项目初始化git推送到服务器
    前端页面调用Spring boot接口发生的跨域问题
    jQuery中异步问题:数据传递
    Git中修复bug
  • 原文地址:https://www.cnblogs.com/breg/p/3714322.html
Copyright © 2020-2023  润新知