Java vs Rust: Hello World HTTP 服务器性能测试
在本文中,我将比较Java的本机HTTP服务器和Rust的Hyper HTTP服务器。根据我的研究,我发现 Hyper 是 Rust 方面最受欢迎的服务器选择。如果有更好和流行的替代品,请告诉我。
Rust 是一种生成机器代码的编译语言,而 Java 也是一种生成在 JVM 内部运行的字节代码的编译语言。这种比较可能不太公平。无论如何,让我们运行测试并检查结果。
在继续之前,其他比较如下:
- Bun vs Rust: Hello World HTTP 服务性能测试
- Deno vs Rust: Hello World HTTP 服务性能测试
- Go vs Rust: Hello World HTTP 服务性能测试
测试设置
这些测试在具有16G RAM的MacBook Pro M1上执行。
软件版本为:
- Java v20
- Rust v1.68.2
在这两种情况下,hello world HTTP 服务器代码如下所示:
Java
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class NativeHelloWorldServer {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(3000), 0);
server.createContext("/", new MyHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
}
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange t) throws IOException {
String response = "Hello world!";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
Rust
use std::convert::Infallible;
use std::net::SocketAddr;
use bytes::Bytes;
use http_body_util::Full;
use hyper::server::conn::http1;
use hyper::service::service_fn;
use hyper::{Request, Response};
use tokio::net::TcpListener;
async fn hello(_: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {
let response = Response::builder()
.header("Content-type", "text/plain")
.body(Full::new(Bytes::from("Hello World!")))
.unwrap();
Ok(response)
}
#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr: SocketAddr = ([127, 0, 0, 1], 3000).into();
let listener = TcpListener::bind(addr).await?;
loop {
let (stream, _) = listener.accept().await?;
tokio::task::spawn(async move {
if let Err(err) = http1::Builder::new()
.serve_connection(stream, service_fn(hello)).await {
println!("Error serving connection: {:?}", err);
}
});
}
}
Cargo.toml
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[dependencies]
bytes = "1"
hyper = { version = "1.0.0-rc.3", features = ["full"] }
tokio = { version = "1", features = ["full"] }
http-body-util = "0.1.0-rc.2"
运行测试
每个测试针对 5M(500 万个)请求执行。
对 10、100 和 300 个并发连接执行测试。
负载测试是使用庞巴迪HTTP测试工具进行的。
下表显示了每个并发级别的结果:
分析
Rust 在各个方面都完全击败了 Java,无论是 RPS、延迟、CPU 还是内存。
获胜者:Rust
再一次,其他比较在这里: