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.mzph.cn/news/260795.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第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​…

HDU - 1723 - Distribute Message

先上题目: 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入门!...

你在用什么软件进行图像处理呢?厌倦了鼠标和手指的拖拖点点,想不想用程序和代码进行图像的高效处理,Python作为简单高效又很强大的一门编程语言,对于图像的处理自然也是轻松拿下,听起来是不是很酷很极客,那…

创建一个追踪摄像机(2)

为了生成曲线,函数需要通过4个在沿着重量值在0和1之间的路径上连贯的位置。由于重量在这些2个值之间增加,曲线返回在更远的路径上的坐标。 当所提供的重量值为0,曲线将返回正确的坐标在第二个输入坐标。当所提供的重量值为1,曲线将…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波12 - 空间域滤波基础 - 卷积运算(numpy 实现的三种卷积运算)

这篇文章比较长,请耐心看空间域滤波基础线性滤波可分离滤波器核空间域滤波和频率域滤波的一些重要比较如何构建空间滤波器第一种卷积方法(公式法)第二种卷积的方法(可分离核)第三种方法(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 现有公园游船租赁处请你编写一个租船管理系统。当游客租船时,管理员输入船号并按…

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 …

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波13 - 平滑低通滤波器 -盒式滤波器核

这里写目录标题平滑&#xff08;低通&#xff09;空间滤波器盒式滤波器核平滑&#xff08;低通&#xff09;空间滤波器 平滑&#xff08;也称平均&#xff09;空间滤波器用于降低灰度的急剧过渡 在图像重取样之前平滑图像以减少混淆用于减少图像中无关细节平滑因灰度级数量不…

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…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波14 - 平滑低通滤波器 -高斯滤波器核的生成方法

目录平滑&#xff08;低通&#xff09;空间滤波器低通高斯滤波器核统计排序&#xff08;非线性&#xff09;滤波器平滑&#xff08;低通&#xff09;空间滤波器 平滑&#xff08;也称平均&#xff09;空间滤波器用于降低灰度的急剧过渡 在图像重取样之前平滑图像以减少混淆用…

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

turtle库是Python语言中一个很流行的绘制图像的函数库&#xff0c;想象一个小乌龟&#xff0c;在一个横轴为x、纵轴为y的坐标系原点&#xff0c;(0,0)位置开始&#xff0c;它根据一组函数指令的控制&#xff0c;在这个平面坐标系中移动&#xff0c;从而在它爬行的路径上绘制了图…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波15 - 锐化高通滤波器 -拉普拉斯核(二阶导数)

目录锐化&#xff08;高通&#xff09;空间滤波器基础 - 一阶导数和二阶导数的锐化滤波器二阶导数锐化图像--拉普拉斯锐化&#xff08;高通&#xff09;空间滤波器 平滑通过称为低通滤波类似于积分运算锐化通常称为高通滤波微分运算高过&#xff08;负责细节的&#xff09;高频…

在python是什么意思_python 的 表示什么

python代码里经常会需要用到各种各样的运算符&#xff0c;这里我将要和大家介绍的是Python中的&&#xff0c;想知道他是什么意思吗&#xff1f;那就和小编一起来了解一下吧。&是位运算符-与&#xff0c;类似的还有|&#xff08;或&#xff09;&#xff0c;!(非)。 整数…

DevExpress控件GridControl中的布局详解 【转】

DevExpress控件GridControl中的布局详解 【转】 2012-10-24 13:27:28| 分类&#xff1a; devexpress | 标签&#xff1a;devexpress |举报|字号 订阅 http://www.cnblogs.com/martintuan/archive/2011/03/05/1971472.html 进行DevExpress控件GridControl的使用时&#xff…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波16 - 锐化高通滤波器 - 钝化掩蔽和高提升滤波

目录锐化&#xff08;高通&#xff09;空间滤波器钝化掩蔽和高提升滤波锐化&#xff08;高通&#xff09;空间滤波器 平滑通过称为低通滤波类似于积分运算锐化通常称为高通滤波微分运算高过&#xff08;负责细节的&#xff09;高频&#xff0c;衰减或抑制低频 钝化掩蔽和高提…

python画圆并填充图形颜色_如何使用python设计语言graphics绘制圆形图形

在python设计语言中&#xff0c;可以利用第三方包graphics绘制不同的图形&#xff0c;有圆形、直线、矩形等。如果想要绘制一个圆形&#xff0c;可以设置圆形的半径和坐标位置。下面利用一个实例说明绘制圆形&#xff0c;操作如下&#xff1a;工具/原料 python 截图工具 方法/步…

设计模式学习-工厂方法模式

在上文(设计模式学习-简单工厂模式)的模拟场景中&#xff0c;我们用简单工厂模式实现了VISA和MASTERARD卡的刷卡处理&#xff0c;系统成功上线并运行良好&#xff0c;突然有一天老大跑来说&#xff0c;我们的系统需要升级&#xff0c;提供对一般银联卡的支持。怎么办&#xff1…

word2010激活工具使用方法

1、关闭杀毒&#xff0c;关闭正打开着的word文档 2、执行Activator_v1.2.exe-->Activation Office 2010VL --》按1 --》完毕。 3、打开word--》文件--》帮助--》看右上角。 2、【补充】使用 Office 2010 Toolkit 下载地址&#xff1a; http://vdisk.weibo.com/s/yoz9R 或…