C++和Rust_后端程序員一定要看的語言大比拼:Java vs. Go vs. Rust

bfbf8845757c5bf8540ad5173fcd1929.png

這是Java,Go和Rust之間的比較。這不是基準測試,更多是對可執行文件大小、內存使用率、CPU使用率、運行時要求等的比較,當然還有一個小的基準測試,可以看到每秒處理的請求數量,我將嘗試對這些數字進行有意義的解讀。

為了嘗試將蘋果與蘋果進行比較(也許是?),我在此比較中使用每種語言編寫了一個Web服務。Web服務非常簡單,它提供了三個REST服務端點(endpoint)。

6cc901fe9e232b74b65589fd786a4a0a.png

Web服務提供的服務端點

這三個Web服務的代碼倉庫托管在github上。

編譯后的二進制文件尺寸

有關如何構建二進制文件的一些信息。對于Java,我使用maven-shade-plugin和mvn package命令將所有內容構建到一個大的jar中。對于Go,我使用go build。最后,我使用了cargo build --release構建Rust服務的二進制文件。

fb940546b39ec331cfc1cb3328613dea.png

每個程序的大小(以兆字節為單位)

編譯后的文件大小還取決于所選的庫/依賴項,因此,如果依賴項的身軀臃腫,則編譯后的程序也將難以幸免。在我的特定情況下,針對我選擇的特定庫,以上是程序編譯后的大小。

在后續的一個單獨小節中,我會把這三個程序都構建并打包為docker鏡像,并列出它們的大小,以顯示每種語言所需的運行時開銷。下面有更多詳細信息。

內存使用情況

空閑狀態

15ab0c95ebca8722e2bfc67381730f15.png

每個應用程序在內存空閑時的內存使用情況

什么?Go和Rust版本顯示空閑時內存占用量的條形圖在哪里?好了,它們在那里,只有JVM啟動的程序在空閑狀態時消耗160 MB以上的內存,它什么也沒做。Go應用程序僅使用0.86 MB,Rust應用也僅使用了0.36 MB。這是一個巨大的差異!在這里,Java使用的內存比Go和Rust應用使用的內存高出兩個數量級,只是空占著內存卻什么都不做。那是巨大的資源浪費。

服務REST請求

讓我們使用wrk發起訪問API的請求,并觀察內存和CPU使用情況,以及在我的計算機上三個版本程序的每個端點每秒處理的請求數。

wrk -t2 -c400 -d30s http://127.0.0.1:8080/hello wrk -t2 -c400 -d30s http://127.0.0.1:8080/greeting/Janewrk -t2 -c400 -d30s http://127.0.0.1:8080/fibonacci/35

上面的wrk命令使用兩個線程并在連接池中保持400個打開的連接,并重復調用GET端點,持續30秒。這里我僅使用兩個線程,因為wrk和被測程序都在同一臺計算機上運行,所以我不希望它們在可用資源(尤其是CPU)上相互競爭(太多)。

每個Web服務都經過單獨測試,并且在每次運行之間都重新啟動了Web服務。

以下是該程序的每個版本的三個運行中的最佳結果。

  • /hello

該端點返回Hello,World!信息。它分配字符串“ Hello,World!” 并將其序列化并以JSON格式返回。

c95297594b4c0a2b822fb1eb30aa78e9.png

/hello端點的CPU使用率

c3f7e9c400209d7efee96b6aa2b4fbfd.png

/hello端點的內存使用情況

ebc762ae5376ef192d7471d0c9a2397d.png

/hello端點處理的每秒請求數

  • /greeting/{name}

該端點接受一個段路徑參數{name},然后格式化字符串“Hello,{name}!”,序列化并以JSON格式的問候消息返回。

28b3e2873af3a6f064facabdce415958.png

/greeting端點的CPU使用率

6ed83d1f3a5f3a4bac58bd6f5f305134.png

/greeting端點的內存使用情況

e064743595576a3cdf9130c913823f41.png

/greeting端點處理的每秒請求數

  • /fibonacci/{number}

該端點接受一個段路徑參數{number},并返回序列化為JSON格式的斐波納契數和輸入數。

對于這個特定的端點,我選擇以遞歸形式實現它。我毫不懷疑,迭代實現會產生更好的性能結果,并且出于生產目的,應該選擇一種迭代形式,但是在生產代碼中,有些情況下必須使用遞歸(并非專門用于計算第n個斐波那契數 )。為此,我希望該實現涉及大量CPU棧分配。

9aaf205dac2a2b84398eeaf62d9ae52c.png

/fibonacci端點的CPU使用率

c3fe4a39e348a82ca2566fd2260b9187.png

/fibonacci端點的內存使用情況

7469e304e4eb20c76330948eef707287.png

/fibonacci端點處理的每秒請求數

在Fibonacci端點測試期間,Java是唯一一個有150個請求超時的實現,如下面wrk的輸出所示。

4993e44404ed4c8ef51032d621e7e350.png

超時時間

fae3c80ee59a42aefeff5d4786f3a13e.png

/fibonacci端點的延遲

運行時大小

為了模擬現實世界中的云原生應用程序,并避免“它僅可以在我的機器上運行!”,我分別為這三個應用程序創建了一個docker鏡像。

Docker文件的源代碼包含在代碼庫相應程序文件夾下。

作為我使用過的Java應用程序的基礎鏡像,openjdk:8-jre-alpine是已知大小最小的鏡像之一,但是,這附帶了一些警告,這些警告可能適用于您的應用程序,也可能不適用于您的應用程序,主要是alpine鏡像在處理環境變量名稱方面不是posix兼容的,因此您不能在Dockerfile中使用ENV中的(點)字符(不過這沒什么大不了的),另一個是alpine Linux鏡像是使用musl libc而不是glibc編譯的,這意味著如果您的應用程序依賴于需要glibc,它可能無法正常工作。不過,在這里,alpine鏡像工作是正常的。

至于應用程序的Go版本和Rust版本,我已經對其進行了靜態編譯,這意味著它們不希望在運行時鏡像中存在libc(glibc,musl…等),這也意味著它們不需要運行OS的基本鏡像。因此,我使用了scratch docker鏡像,這是一個no-op鏡像,以零開銷托管已編譯的可執行文件。

我使用的Docker鏡像的命名約定為{lang}/webservice。該應用程序的Java,Go和Rust版本的鏡像大小分別為113、8.68和4.24 MB。

afe83654c421f1493adca82b595668e0.png

最終Docker鏡像大小

結論

7399e3f5f6d787bcaafdac9b5c2373aa.png

三種語言的比較

在得出任何結論之前,我想指出這三種語言之間的關系。Java和Go都是支持垃圾回收的語言,但是Java會提前編譯為在JVM上運行的字節碼。啟動Java應用程序時,JIT編譯器會被調用以通過將字節碼編譯為本地代碼來優化字節碼,以提高應用程序的性能。

Go和Rust都提前編譯為本地代碼,并且在運行時不會進行進一步的優化。

Java和Go都是支持垃圾收集的語言,具有**STW(停止世界)**的副作用。這意味著,每當垃圾收集器運行時,它將停止應用程序,進行垃圾收集,并在完成后從停止的地方恢復應用程序。大多數垃圾收集器需要停止運行,但是有些實現似乎不需要這樣做。

當Java語言在90年代創建時,其最大的賣點之一是一次編寫,可在任何地方運行。當時這非常好,因為市場上沒有很多虛擬化解決方案。如今,大多數CPU支持虛擬化,這種虛擬化抵消了使用某種語言進行開發的誘惑(該語言承諾可以運行在任何平臺上)。Docker和其他解決方案以更為低廉的代價提供虛擬化。

在整個測試中,應用程序的Java版本比Go或Rust對應版本消耗了更多的內存,在前兩個測試中,Java使用的內存大約增加了8000%。這意味著對于實際應用程序,Java應用程序的運行成本會更高。

對于前兩個測試,Go應用程序使用的CPU比Java少20%,同時處理比java版多出38%的請求。另一方面,Rust版本使用的CPU比Go減少了57%,而處理的請求卻增加了13%。

第三次測試在設計上是占用大量CPU的資源,因此我想從中擠出CPU的每一分。Go和Rust都比Java多使用了1%的CPU。而且我認為,如果wrk不是在同一臺計算機上運行,那么這三個版本都會使CPU達到100%的上限值。在內存方面,Java使用的內存比Go和Rust多2000%。Java可以處理的請求比Go多出20%,而Rust可以處理的請求比Java多出15%。

在撰寫本文時,Java編程語言已經存在了將近30年,這使得在市場上尋找Java開發人員變得相對容易。另一方面,Go和Rust都是相對較新的語言,因此與Java相比,自然而然的開發人員的數量更少些。不過,Go和Rust都擁有很大的吸引力,許多開發人員正在將它們用于新項目,并且有許多使用Go和Rust的生產中正在運行的項目,因為簡單地說,就資源而言,它們比Java更有效。

在編寫本文的程序時,我同時學習了Go和Rust。就我而言,Go的學習曲線很短,因為它是一種相對容易掌握的語言,并且與其他語言相比語法很小。我只用了幾天就用Go編寫了程序。關于Go需要注意的一件事是編譯速度,我不得不承認,與Java/C/C++/Rust等其他語言相比,它的速度非常快。該程序的Rust版本花了我大約一個星期的時間來完成,我不得不說,大部分時間都花在弄清borrow checker向我要什么上。Rust具有嚴格的所有權規則,但是一旦掌握了Rust的所有權和借用概念,編譯器錯誤消息就會突然變得更加有意義。違反借閱檢查規則時,Rust編譯器對您大吼的原因是因為編譯器希望在編譯時證明已分配內存的壽命和所有權。這樣做可以保證程序的安全性(例如:沒有懸掛的指針,除非使用了不安全(unsafe)的代碼逃離檢查),并且在編譯時確定了釋放位置,從而消除了垃圾收集器的需求和運行時成本。當然,這是以學習Rust的所有權系統為代價的。

在競爭方面,我認為Go是Java(通常是JVM語言)的直接競爭對手,但不是Rust的競爭對手。另一方面,Rust是Java,Go,C和C ++的重要競爭對手。

由于他們的效率,我看到了自己將會在Go和Rust中編寫更多的程序,但是很可能在Rust中編寫更多的程序。兩者都非常適合Web服務,CLI,系統程序(…etc)開發。但是,Rust比Go具有根本優勢。它不是垃圾收集的語言,與C和C++相比,它可以安全地編寫代碼。例如,Go并不是特別適合用于編寫OS內核,而這里又是Rust的亮點,并與C/C ++競爭,因為它們是使用OS編寫的長期存在和事實上的語言。Rust與C/C++競爭的另一種方式在嵌入式世界中,我將繼續進行討論。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260795.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260795.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260795.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Hdu 2015 偶數求和

題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2040。水題。CODE&#xff1a;1 #include <stdio.h>2 #include <stdlib.h>3 #include <string.h>4 #include <math.h>5 using namespace std;6 7 const int maxn 102;8 9 int save[ma…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波11 - 直方圖處理 - 使用直方圖統計量增強圖像

使用直方圖統計量增強圖像 全局均值和方差 μn∑i0L?1(ri?m)np(ri)(3.24)\mu_{n} \sum_{i0}^{L-1} (r_{i} - m)^{n} p(r_{i}) \tag{3.24}μn?i0∑L?1?(ri??m)np(ri?)(3.24) m∑i0L?1rip(ri)(3.25)m \sum_{i0}^{L-1} r_{i} p(r_{i}) \tag{3.25}mi0∑L?1?ri?p(ri?…

數據結構 --- 堆

to be continued轉載于:https://www.cnblogs.com/zhongzhiqiang/p/5808564.html

HDU - 1723 - Distribute Message

先上題目&#xff1a; Distribute Message Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1186 Accepted Submission(s): 547 Problem DescriptionThe contest’s message distribution is a big thing in pre…

nodejs 圖片處理模塊 rotate_學會Pillow再也不用PS啦——Python圖像處理庫Pillow入門!...

你在用什么軟件進行圖像處理呢&#xff1f;厭倦了鼠標和手指的拖拖點點&#xff0c;想不想用程序和代碼進行圖像的高效處理&#xff0c;Python作為簡單高效又很強大的一門編程語言&#xff0c;對于圖像的處理自然也是輕松拿下&#xff0c;聽起來是不是很酷很極客&#xff0c;那…

創建一個追蹤攝像機(2)

為了生成曲線&#xff0c;函數需要通過4個在沿著重量值在0和1之間的路徑上連貫的位置。由于重量在這些2個值之間增加&#xff0c;曲線返回在更遠的路徑上的坐標。 當所提供的重量值為0&#xff0c;曲線將返回正確的坐標在第二個輸入坐標。當所提供的重量值為1&#xff0c;曲線將…

Xcodebuild自動打包

#! /bin/bash #firtoken 29b441056e1e17c984cb32fadadsdddd shell_dirdirname $0 TARGET_NAME"SmartLock" DIR_PATH/Users/用戶名/Desktop/SmartLock SIGN"iPhone Distribution:******" PROFILE"66d127d6-7963-4c20-ac8b-47e4f0fe8742" TEMP_DIR…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波12 - 空間域濾波基礎 - 卷積運算(numpy 實現的三種卷積運算)

這篇文章比較長&#xff0c;請耐心看空間域濾波基礎線性濾波可分離濾波器核空間域濾波和頻率域濾波的一些重要比較如何構建空間濾波器第一種卷積方法&#xff08;公式法&#xff09;第二種卷積的方法&#xff08;可分離核&#xff09;第三種方法&#xff08;img2col)這是分離核…

hdu_1861_游船出租_201402282130

游船出租 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7238 Accepted Submission(s): 2411 Problem Description 現有公園游船租賃處請你編寫一個租船管理系統。當游客租船時&#xff0c;管理員輸入船號并按…

acer清理工具 clear下載_SolidWorks綠色版下載-SolidWorks完全清理工具v1.0免費版

SolidWorks完全清理工具(SWCleanUninstall)是一款綠色免費的SolidWorks完全卸載工具。很多SolidWorks安裝不成功都是因為之前安裝錯誤做成軟件殘留。這款工具可以完全清理很多SolidWorks留下的注冊表垃圾。軟件核心功能1、SWCleanUninstall可以直接刪除電腦上的SolidWorks軟件2…

ZOJ1221 Risk 圖形的遍歷

一開始做圖形遍歷的題都是用鏈表做的&#xff0c;這次用數組體會到了方便但就是有點浪費。 不過題目給的內存限制已經足夠了。 View Code 1 #include<cstdio>2 #include<cstdlib>3 #include<cstring>4 #include<queue>5 #include<iostream>6 7 …

Android 從AndroidManifest獲取meta-data

語法如下&#xff1a; <meta-data android:name"string"android:resource"resource specification"android:value"string" /><meta-data>標簽可以作為子標簽&#xff0c;可以被包含在<activity>、<application> 、<s…

trim()函數

參數string&#xff1a;string類型&#xff0c;指定要刪除首部和尾部空格的字符串返回值String。 函數執行成功時返回刪除了string字符串首部和尾部空格的字符串&#xff0c;發生錯誤時 返回空字符串&#xff08;""&#xff09;。 如果參數值為null時&#xff0c;會拋…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波13 - 平滑低通濾波器 -盒式濾波器核

這里寫目錄標題平滑&#xff08;低通&#xff09;空間濾波器盒式濾波器核平滑&#xff08;低通&#xff09;空間濾波器 平滑&#xff08;也稱平均&#xff09;空間濾波器用于降低灰度的急劇過渡 在圖像重取樣之前平滑圖像以減少混淆用于減少圖像中無關細節平滑因灰度級數量不…

python中str用法_python數據類型之str用法

1、首字母大寫 語法&#xff1a;S.capitalize() ->str title "today is a good day"title_catitle.capitalize() print(title_ca) 結果&#xff1a;today is a good day 2、大寫轉小寫 1 語法&#xff1a;S.casefold() ->str2 3 title "TODAY is a GOOD …

WPF 窗體設置

WPF 當窗體最大化時控件位置的大小調整&#xff1a; View Code 1 <Window x:Class"WpfApplication1.MainWindow"2 xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"3 xmlns:x"http://schemas.microsoft.com/wi…

Git實踐

Git是什么自不必說。Git和gitlab安裝和實踐在后邊的倆篇中會寫。本篇僅重點寫Git自動部署。Git同樣有Hooks,可以用于各種需求。可以控制提交commit名稱&#xff0c;可以控制代碼規范&#xff0c;也當然包含以下要介紹的自動部署&#xff0c;也不僅包含這些。Git自動部署簡單的思…

第3章 Python 數字圖像處理(DIP) - 灰度變換與空間濾波14 - 平滑低通濾波器 -高斯濾波器核的生成方法

目錄平滑&#xff08;低通&#xff09;空間濾波器低通高斯濾波器核統計排序&#xff08;非線性&#xff09;濾波器平滑&#xff08;低通&#xff09;空間濾波器 平滑&#xff08;也稱平均&#xff09;空間濾波器用于降低灰度的急劇過渡 在圖像重取樣之前平滑圖像以減少混淆用…

易經0

--- 陽爻 - - 陰爻 從下往上 畫爻 (yao) 三畫卦 --> 2^38 (八卦) 那天有空用程序 解析一下 六畫卦 --> 2^664(卦) 卦形記憶歌&#xff1a;宋代朱熹的《周易本義》寫了《八卦取象歌》幫人記卦形&#xff1a; 乾三連&#xff0c;坤六斷&#xff1b;震仰盂&#xff0c;艮覆碗…

python3.7怎么安裝turtle_python怎么安裝turtle

turtle庫是Python語言中一個很流行的繪制圖像的函數庫&#xff0c;想象一個小烏龜&#xff0c;在一個橫軸為x、縱軸為y的坐標系原點&#xff0c;(0,0)位置開始&#xff0c;它根據一組函數指令的控制&#xff0c;在這個平面坐標系中移動&#xff0c;從而在它爬行的路徑上繪制了圖…