低延遲系統請選擇Java而不是C++ - stackoverflow

banq發表於2021-03-06

在開發低延遲的軟體系統時,人們普遍認為,除了C ++之外,您使用其他任何語言是瘋狂的,因為其他任何語言都具有很高的延遲。但是,我在這裡是要說服您使用相反的、違反直覺的、幾乎是異端的概念:在軟體系統中實現低延遲時,Java更好。
在本文中,我想以一個特殊的軟體示例為例,該軟體具有低延遲性。交易系統。但是,我在這裡所做的論點幾乎可以應用於需要或希望有低延遲的任何情況。只是相對於我有經驗的開發領域而言,討論起來更加容易。事實是,延遲可能很難衡量。
這一切都取決於您對“低延遲”的定義。讓我解釋…
 

接受的智慧
讓我們先來看一下為什麼您應該選擇C ++來構建高速,低延遲的系統的原因。 
由於C ++更接近基本知識,因此大多數開發人員都會告訴您,使用該語言進行編碼具有固有的速度優勢。在低延遲情況下(例如高速交易),微秒可以使可行的軟體與過時的磁碟空間浪費有所不同,C ++被視為黃金標準。
或者至少曾經是。現實是,如今,許多大型銀行和經紀人都使用Java編寫的系統。
C ++在執行程式碼時可能是“低延遲”,但是在推出新功能甚至尋找可以編寫它的開發人員時,絕對不是低延遲。 
 

Java和C ++之間的(實際)區別
關於開發環境中的Java和C ++之間的真正差異,這僅僅是開發時間的開始。因此,為了瞭解每種語言在這種情況下的真正價值,讓我們對其進行一些整理。
首先,重要的是要記住在大多數情況下C ++比Java更快的實際原因:C ++指標是記憶體中變數的地址。這意味著軟體可以直接訪問各個變數,而無需遍歷計算量大的表來查詢它們。或者至少可以告訴他們它們在哪裡,因為使用C ++,您通常必須顯式地管理物件的生存期和所有權。 
這樣的結果是,除非您真的非常擅長編寫它(一項技能可能需要數十年才能掌握),否則C ++將需要數小時(或數週)的除錯時間。而且,正如任何嘗試除錯Monte Carlo引擎或PDE求解器的人都會告訴您的那樣,嘗試在基本級別上除錯記憶體訪問可能會非常耗時。僅僅一個壞了的指標就很容易使整個系統崩潰,因此交付用C ++編寫的新版本確實很恐怖。
當然,這還不是全部。那些喜歡用C ++程式設計的人(所有這三個人)都會指出Java中的垃圾收集器(GC)遭受非線性延遲尖峰的困擾。使用舊版系統時尤其如此,因此在不破壞客戶系統的情況下向Java程式碼交付更新可能會使它們變得如此緩慢以致無法使用。
對此,我要指出,為減少Java GC在過去十年中產生的延遲,已經做了很多工作。例如,LMAX Disruptor是一個用Java編寫的低延遲交易平臺,但也被構建為一個框架,該框架對其執行的硬體具有“機械同情”,並且是無鎖的。 
如果您要構建使用持續整合和交付(CI / CD)流程的系統,則可以進一步緩解問題,因為CI / CD允許自動部署經過測試的程式碼更改。這是因為CI / CD提供了一種迭代的方法來提高GC延遲,在這種方法中,可以逐步改進Java並針對特定的硬體環境進行Java定製,而無需花費大量資源就可以在交付之前為不同的硬體規格準備程式碼。 
由於IDE對Java的支援比對C ++的支援要先進得多,因此大多數環境(Eclipse,IntelliJ,IDEA)都可以重構Java。這意味著大多數IDE將允許您最佳化程式碼以使其以低延遲執行,而該功能在使用C ++時仍然受到限制。 
即使在原始效能上與C ++不完全匹配,大多數開發人員也將比在C ++中更容易在Java中達到可接受的效能。真正的延遲殺手是介於有想法和釋出程式碼之間。 
 

我們所說的更快是什麼意思?
實際上,有充分的理由質疑C ++確實比Java真正“更快”或“更低的延遲”。在這一點上,我知道我進入了一些暗淡的水域,並且許多開發人員可能開始質疑我的理智。但是,請聽我說。
首先,有一點(有點荒謬):如果您有兩個開發人員,一個是用C ++編寫的,另一個是用Java編寫的,並且您要求他們從頭開始編寫一個用於高速交易的平臺:在陣列邊界之外建立索引在Java和C ++中都是錯誤。如果您不小心在C ++中執行了此操作,則可能會出現段錯誤,或者(更常見的是)您會得到一些隨機數,即使對於有經驗的開發人員也不會有任何意義。在Java中,索引越界總是丟擲ArrayIndexOutOfBoundsException。這意味著在Java中除錯非常容易,因為錯誤往往會立即引發錯誤,並且更容易跟蹤錯誤的位置。  
此外,至少就我的經驗而言,Java(在大多數環境中)僅擅長識別哪些程式碼段不需要執行以及哪些程式碼對您的軟體正常執行至關重要。當然,您可以花幾天時間調整C ++程式碼,使其絕對不包含多餘的程式碼,但是在現實世界中,每個軟體都包含一些膨脹,而Java更擅長自動識別它。
這意味著,在現實世界中,即使在標準的延遲度量上,Java的速度通常也比C ++快。即使不是這樣,語言之間的延遲差異也常常被其他因素淹沒,甚至在高頻交易中也相差甚遠。例如,很多研究表明5G網路的等待時間減少了(據一些分析家稱降至1ms),但是在低等待時間程式設計中,這仍然代表了巨大的效能成本。 
 

Java在低延遲系統中的優勢
在我看來,所有這些因素都構成了使用Java編寫高速交易平臺(實際上,實際上是低延遲系統,不久之後還會有更多內容)的一個無懈可擊的案例。 
但是,只是為了讓C ++發燒友多一點,讓我們看一下使用Java的許多其他原因:

  • 首先,正如我們已經在上面看到的那樣,Java引入您的軟體的任何額外延遲都可能比(至少)在一個必須交易的系統中必須存在的現有延遲接收器(例如網路通訊延遲)小得多。透過之前完成。這意味著在大多數交易情況下,任何(編寫良好的)Java程式碼都可以輕鬆實現與C ++一樣好的效能。
  • Java開發時間的縮短還意味著,在現實世界中,用Java編寫的軟體比C ++可以更迅速地適應變化的硬體(甚至是新穎的交易策略)。
  • 進一步瞭解這一點,您會發現,即使從整個軟體的角度來看,最佳化Java軟體也比C ++中的等效任務更快。正如對低延遲和整個系統的高效率感興趣的Java顧問Peter Lawrey最近對InfoQ所說: “如果您的應用程式將90%的時間花費在10%的程式碼中,則Java會使最佳化工作的難度提高10%,但編寫並維護90%您的程式碼百分比更容易;特別是對於混合能力的團隊。”

 在Java中,除錯,敏捷開發以及對多種環境的適應都變得更加簡單快捷。
  
關於如何實現低延遲的爭論並不是一個新話題,而且對於金融界而言並非唯一。因此,可以從中學習有關其他情況的寶貴經驗。特別是,上面的論點-Java更“好”,因為它更靈活,更具彈性,並且最終可以更快地開發和維護-可以應用於軟體開發的許多領域。
我(個人)更喜歡用Java編寫低延遲系統的原因與過去25年來使該語言取得如此成功的原因相同。Java易於編寫,編譯,除錯和學習,這意味著您可以花更少的時間編寫程式碼,而將更多的時間用於最佳化延遲。最終,在現實世界中,這將導致可靠的更快的交易系統。而且,對於高速交易而言,這才是最重要的。



 

相關文章