標籤:style blog class java tar ext
前幾天在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+"\r\n"); 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."\r\n"); $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/