原文連接:https://www.tandemseven.com/b...java
若是你打開瀏覽器,搜索「Java與Node.js哪一個更快」,你會發現大部分答案聲稱Node.js更快,也有一些人持相反意見。Java使用JIT編譯器,其性能甚至能夠超過C++。在這種狀況下,爲何這麼多人仍是聲稱Node.js要比Java快呢?小編如今就跟你們一塊兒往下看。node
實際檢驗結果git
實際上,在處理原始計算任務方面,Node.js並不比Java快;一旦涉及到IO型任務,Java就沒有競爭力了。也就是說,在典型的Web應用程序執行的任務類型場景中,Node.js運行速度確實比Java更快,在接下來模擬的4種場景測試的結果充分驗證了這一點。github
性能因素數據庫
爲了更好的理解Node.js如何完勝Java,須要考慮到3個性能因素:IO,併發和計算。這三大因素對於提升應用程序的總體運行速度和吞吐量都是有影響的。後端
一、IO數組
根據servlet規範,Java在早幾年前引入的NIO其實是Java編寫後端服務器代碼的標準。在整個規範中,servlet API都假定代碼能夠而且將在每一個級別阻塞。雖然過去幾年規範有所改進,可以容許非阻塞請求處理,但servlet規範的基本範例仍然徹底包含IO阻塞。這意味着以非阻塞方式寫入磁盤或使用JDBC寫入數據庫的操做會阻止處理線程執行任何其餘操做。雖然Java可以以非阻塞的方式工做,可是對於基於servlet技術的Java應用程序來講,實現一個非阻塞服務器仍然是不切實際的。對於Java社區來講,這一點是很是遺憾。瀏覽器
另外一方面,JavaScript徹底支持非阻塞IO。JavaScript API不提供阻塞選項,在每一個級別上強制支持非阻塞API規範。這意味着在執行IO操做時,Node將永遠不會被阻塞,而且在等待IO時,Node將始終能夠自由地處理其餘工做。從而,Node可以很是高效地使用服務器的處理和內存資源。具體來講,Node只需一個線程就能夠同時處理和發出數千個IO操做。緩存
二、併發服務器
在Web框架中,Java和Node以兩種大相徑庭的方式實現併發。
Java:它爲處理的每一個傳入請求指定一個線程。隨着併發請求數的增長,線程數也必須增長。若是計劃同時處理最多100個請求,則須要有100個線程池可供處理。
Node:使用一個線程來處理全部傳入的請求。因爲Node是非阻塞的,它有足夠的時間對全部請求執行全部計算和轉換,同時等待任何IO操做。
三、計算
雖然谷歌的V8 JavaScript引擎將JavaScript編譯成機器代碼,這結果讓人印象深入。可是,在某些場景中,Java是優於Node的。好比,您要讓Java與Node進行純計算PK,計算前5000個素數,那麼Java每次都會輕鬆獲勝。
Web應用程序存在大量的IO操做
Web應用程序執行大量的IO。首先,從瀏覽器接受請求;這是IO操做。其次,應用程序一般從數據庫中獲取請求的數據;這也是IO操做。一旦計算出全部響應數據,應用程序就會將響應數據發送回瀏覽器;這也是IO操做。應用程序可能一直都在維護日誌;這仍是IO操做。實際上,Web應用程序大部分時間都花在IO操做上,而不是計算。
對於Web應用程序而言,它爲每一個請求提供服務,須要執行大量的IO,對比之下,Node要比Java更加的適合。
Web應用程序須要高併發
一般,一個Web應用程序有不少個用戶同時訪問。基於Java必須爲每一個請求的生命週期指定一個線程,因此它須要大量線程來實現併發。若是在同一時間,應用程序的訪問用戶增長,那麼在全部這些線程之間進行時間分割,很快就會變得很是昂貴而且低效。最終,隨着線程數量的增長,操做系統忙着在全部線程之間進行切換,將變得很是繁忙,以致於CPU時間爆滿後沒法作任何實際工做。
這種大規模的狀況下,Node的效率就很明顯了。當Node以最大負載運行時,雖然CPU會很是繁忙,但操做系統可以輕鬆自如的應付。全部的CPU時間都將用於服務請求上。
Java與Node性能PK模擬
爲了證實Node確實能夠超越Java,本文介紹了4種場景,在這些場景中經過使用模擬器來測試這兩種技術的性能。此模擬器的代碼,你們能夠經過下面的連接找到:
https://github.com/johnrjenso...
註釋:
本測試中,爲Java實現模擬阻塞IO。有些人可能會認爲使用阻塞IO並不公平地比較Java的性能,但在本測試中使用阻塞IO的緣由以下:①Java的JDBC規範仍然是一個阻塞規範,這意味,每當有人使用標準JDBC驅動程序鏈接到關係數據庫時,都必須阻塞。② Apache Tomcat 8.5在2016年6月才完成了第一個非阻塞Servlet規範,這意味着絕大多數生產Java應用程序在執行IO時仍會阻塞。所以,由目前大多數組織以阻塞的方式使用Java,因此在本次模擬中,阻塞也是最具備表明性的Java。
場景1:純計算速度
在第一個場景中,選擇一個純計算工做負載來證實Java的計算優點。分別在有和沒有併發的狀況下進行測試模擬,工做負載狀況:
1a:①無併發;②計算500個質數;③執行0個阻塞IO調用。
1b:①有併發;②計算500個質數;③執行0個阻塞IO調用。
測試結果以下:
1a:純計算任務在沒有使用併發時,Java速度是Node的2.1倍左右;
1b:一旦將併發加入到任務中,Java領先Node的速度下降到1.8倍。
場景2:大量IO操做
第二種模擬中,不作任何計算工做,只執行IO任務。分別在有和沒有併發的狀況下進行測試模擬,工做負載狀況以下:
2a:①無併發;②計算0個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
2b:①有併發;②計算0個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
結果以下:
2a:沒有併發時,Node的速度是Java的3.4倍;
2b:有併發時,Node的速度增長到Java的8.5倍。添加併發後,Node與Java之間的差別更加明顯。
場景3:均衡的工做負載
此場景與典型Web應用程序的請求工做負載最接近,模擬中同時執行IO和計算任務,均衡工做負載。一樣,也是在有和沒有併發的狀況下分別模擬。
工做負載狀況:
3a:①無併發;②計算500個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
3b:①有併發;②計算500個質數;③執行4個阻塞IO調用;④處理一個5MB文件。
測試結果:
3a:沒有併發時,Node的速度是Java的1.8倍;
3b:有併發時,Node的速度增長到Java的4.9倍。
場景4:長時間運行的查詢
工做負載狀況:
①計算500個質數;②發出一個很長的阻塞IO調用——10s響應時間;③處理一個5MB文件
測試結果:
Java每秒6個請求;Node每秒64個請求,是Java的10倍
觀察結果可以發現,執行長時間運行的查詢,Java運行的性能大大受影響,但相同場景下,Node的性能幾乎沒有下降。也就是說,Node完勝Java。
結論
在典型Web應用程序的真實場景中,Node確實是比Java運行速度更快、更具可伸縮性。對於Web應用程序開發來講,Node的性能是難以比擬的。因爲Web應用程序大部分時間都在作IO,而且須要高併發,相比之下,Node顯然是最終的贏家。
關於Node.js的性能指標
一、事件循環
事件循環意味着可以在隊列中執行代碼。事件循環能讓Node.js執行非阻塞IO操做。所以,服務器能夠處理無限數量的操做。系統能夠處理異步操做。事件循環這個指標衡量事件處理延遲。
二、實時用戶行爲
實時用戶行爲指的就是用戶(客戶)在使用應用程序時所作的事情。舉個例子,Uber或Netflix用戶可在幾秒鐘內完成業務交易,這就反映出了了Node.js的效率。實時用戶行爲這個指標是測量響應時間的。
三、外部框架
Node.js應用程序也一樣依賴於其餘的服務、系統和數據庫。它可能會鏈接到其餘應用程序,緩存等,所以也必須記住這戲依賴關係。經過這些外部框架,能夠檢查應用程序的響應時間,請求率,錯誤率,內容大小,API,等等。
四、進程內存
Node.js有一個很棒的助手工具——垃圾收集器,它管理應用程序的內存並防止內存泄漏。首先,您能夠測量在GC上花費的時間——運行越屢次,系統中的暫停次數也就越多。其次,還能夠比較每次運行時的內存並檢查構建趨勢。
Node.js的優勢
Node.js是一種非阻塞事件驅動模型,它可以讓開發人員實時構建應用程序。經過推送技術和雙向鏈接,許多大企業都在使用它。那麼,使用Node.js都有哪些好處呢?
小編跟你們一塊兒來看下:
1.速度(在Google JS引擎上運行);
2.非阻塞I/O模式
3.數據流(HTTP請求和響應做爲的單個事件)
4.實時應用(客戶端和服務器端)
5.統一的數據庫查詢(JSON格式)
6.編碼簡單快速
7.開源NPM存儲庫(超過600000個模塊)
8.代理服務器能力
9.快速的開發週期
10.服務器上的業務邏輯
11.適用於Android設備