天天看點

JSP,PHP詳細性能測試一.算術運算二.字元串運算三.資料庫查詢四.檔案操作五.總結六.其它環境簡單測試七.運作時間的擷取

本測試資料真實,但隻做為參考。歡迎大家讨論。

除做比較外,也可供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

讨論位址:

循環n次,并做整型自加運算。

測試代碼:

測試類型

jsp int整型

jsp long整型

jsp long整型2

php

php2

測試代碼

int i=0;

while (i<xxxx)

{

i++;

}

long l=0;

while (l<xxxx)

l++;

l=l+1;

$i=0;

while ($i<xxxx)

$i++;

$i=$i+1;

測試結果(機關:毫秒)

測試結果說明:m-n表示主要波動範圍介于m和n之間;n表示出現次數非常之多的數值或平均值,m(x,y)表示偶爾會出現x,y。以下相同。

xxxx取值

jsplong整型

jsplong整型2

1000

0-1

10000

3-4

6-7

100000

0(16,32)

34-35

51-52

1000000

0(10)

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

java的算術運算,優化得很好,估計是直接的對應cpu的指令,數值再大,算術運算性能都很平穩。

需要注意的是,long的運算時間要比int的運算時間要長一些(畢竟是32位的系統),是以,在無需用到long時,盡量不要用long,而用int.

php是弱類型的變量,算術運算很不盡人意,估計不是直接對應機器碼的算術運算。

php算術運算的過程猜測如下,在運算前需要檢測變量是否是數值,并要将非數值轉換成數值,比如,php可以做這樣的運算:100+"zhoutang",結果等于100.正是因為是弱類型語言,加上運算前的檢測和轉換,是以才導緻算術運算的性能低下。

php的單次運算時間比較穩定,大概每10000次算術加運算花費的時間約為3.5ms

不同的運算方法,也對性能有影響。

字元串連接配接運算對比。

jsp

string str="";

while (str.length()< xxxx)

str+="a";

$str="";

while (strlen($str)< xxxx)

$str.="a";

0-16

1

656-703

9-10

105078-105235

95-103

java的字元串是用對象處理,很明顯,在字元串的比較過程中,java比php差很遠。(因為字元串操作,很大部分要做連接配接,這裡隻比較連接配接運算,另外粗略比較了一下substring,兩者的差别不是很大)

php的字元串運算,估計很多是直接調用c的字元串函數,是以效率會高很多。

在做web開發中,字元串的連接配接操作還是很頻繁的(包括很多時候生成sql字元串),是以,在算術運算和字元串運算兩個方面,java(jsp)優勢不明顯,與php各有所長。

循環n次做資料庫打開,查詢,關閉操作。主要對jsp直接連資料庫,jsp連接配接池連資料訓,php直接連資料庫,php持久連資料庫做比較。

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;

while (i<xxx)

con=drivermanager.getconnection(dburl,dbuser,dbpwd);

stmt=con.createstatement();

stmt.executeupdate(strsql);

stmt.close();

con.close();

stmt=null;

con=null;

jsp連接配接池

context ctx=new initialcontext();

datasource

ds=(datasource)ctx.lookup("java:comp/env/jdbc/mysql");

string strsql="update tbluser set userlc=userlc+1 where

con=ds.getconnection();

$dbhost="localhost";

$dbuser="root";

$dbpwd="";

$dbname="zhoutang";

$strsql="update tbluser set

userlc=userlc+1 where userid=100";

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);

php持久連接配接

$strsql="update tbluser set userlc=userlc+1 where

mysql_pconnect($dbhost, $dbuser, $dbpwd)

    or die(‘could not connect:

‘ . mysql_error());

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

普通連接配接,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系統都會上傳或對檔案操作。

綜合測試各種檔案操作,測試的過程是首先判斷某檔案是否存在,存在的話删除檔案,再建立檔案,再往檔案裡寫一定長度的内容。整個過程循環n次。

string filename="jsp.txt";

string

filepath=request.getrealpath("");

int

j=0;

file f=new

file(filepath,filename);

if(f.exists())

f.delete();

f.createnewfile();

filewriter fw=new filewriter(filepath+file.separator+filename);

while (j<2*i)

fw.write(j+"\r\n");

j++;

fw.close();

$filename="./php.txt";

while

($i<xxxx)

if (file_exists($filename))

unlink($filename);

$handle=fopen($filename,"x");

$j=0;

($j<2*$i)

fwrite($handle,$j."\r\n");

$j++;

fclose($handle);

265-292(326,431)

346-367

1703-2065

3256-3474

4062-4398

9316-9348

這個測試結果有點意外,本以為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秒)。

以上資料隻能做為參考,同樣的程式,在其它配置的系統,我也做了簡單的測試:

(安裝東西比較多,比較亂,運作一年多沒重裝,由于是工作機,是以作業系統對應用程式優化,而不是對後端服務優化;所測得的資料,比xp下測得的資料要大很多,比如php連接配接mysql循環500次,大約需要16000ms。),粗略的測試的結果是:

算術運算和字元串運算:算術運算,jsp領先很多,字元串運算,php領先很多,和測試機的結果一緻。

連接配接資料庫:php與jsp連mysql速度差距不大,php大概快20%左右,奇怪的是我用pconnect連與connect是一樣的結果,未測試jsp的連接配接池。估計jsp用連接配接池會快很多。

檔案操作:php的檔案操作比jsp性能高出約30%!與測試機的結果有點相差比較大,php領先。

算術運算和字元串運算:和其它環境測試結果一緻,jsp在算術運算時領先,php在字元串運算時領先很多很多。

連接配接資料庫:執行500次循環,php用connect連接配接,花費185ms,php使用pconnect連接配接,花費70ms;jsp未用連接配接池,花費2030ms。

檔案操作:jsp領先很多,1000次循環,jsp花費1500ms左右,php花費7000ms左右。

不管什麼平台系統,測試結果表明,jsp和php在做web開發時,性能差距不大,隻能說各有所長,jsp在資料庫操作以及字元串操作方面不如php,而php在檔案操作及算術運算是,不及jsp。

此外,同種語言,在不同的平台表現也不一樣,根據我的測試結果表明,linux下php,jsp的性能都要優于windows的。

語言

如何擷取運作時間

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>");

$timestart=0;

$timeend=0;

$timestart=mictime();

$timeend=mictime();

echo

"開始時間:".$timestart."毫秒<br>";

"結束時間:".$timeend."毫秒<br>";

"花費時間:".($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/