Para integrações de aplicações é muito comum utilizarmos APIs utilizando protocolo HTTP, permitindo a comunicação entre sistemas, aplicativos e serviços.
A escolha da linguagem que será utilizada pra desenvolver determinada API irá impactar diretamente e significativamente o desempenho e a eficiência do serviço criado, então é preciso conhecer muito bem o produto que está sendo desenvolvido, seu potencial e o quanto precisará escalar, pra que a escolha da tecnologia não seja um problema pra sua aplicação.
Neste artigo vou comparar Rust (Actix), Golang (Std), Java (Quarkus), Nodejs (Express) e Python (Sanic e FastAPI), para avaliar como cada uma delas reagem com uma tarefa simples, retornar uma mensagem “Hello from
Para realizar uma comparação justa e precisa entre essas linguagens e frameworks, utilizaremos a mesma máquina de teste e as seguintes configurações:
Todos os servidores serão configurados para responder na porta 8080.
Os seguintes trechos de código foram utilizados para o benchmark, com seus respectivos comandos para iniciar a aplicação, e todos esses exemplos foram testados com o seguinte comando.
Como vocês já devem ter percebido no último artigo que fiz “ownership de variáveis” perceberam que Rust é conhecido por sua segurança e desempenho. O framework Actix é altamente concorrente e promete alto desempenho, e também é o framework que estou estudando.
use actix_web::{App, HttpServer, HttpResponse, Responder, get};
#[get("/")]
async fn hello() -> impl Responder {
HttpResponse::Ok().body("Hello world!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(hello)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Go é uma linguagem de programação projetada para eficiência e desempenho. Utilizei a biblioteca padrão, pois fiz o mesmo teste utilizando Gin e a performance com a biblioteca padrão foi melhor.
package main
import (
"io"
"net/http"
)
func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8080", nil)
}
func helloWorld(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world from Golang!")
}
Python é conhecido por sua legibilidade e facilidade de uso. FastAPI é um framework web moderno e de alto desempenho para Python, resolvi colocar o Sanic nos testes por ter excelente desempenho também, embora nunca tenha trabalhado com ele.
Sanic:
from sanic import Sanic
from sanic.response import text
app = Sanic("BenchmarkHelloWorldApp")
@app.get("/")
async def hello_world(_):
return text("Hello, world from Sanic!")
FastAPI:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return "Hello World from Fastapi!"
Java é uma linguagem de programação amplamente utilizada, e Quarkus é um framework Java nativo de nuvem conhecido por sua inicialização rápida.
package org.acme;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello from Java Quarkus!";
}
}
Node.js é uma plataforma de execução JavaScript amplamente utilizada, e Express é um framework Node.js conhecido por sua simplicidade e flexibilidade no desenvolvimento de aplicativos da web.
const express = require("express");
const app = express();
const port = 8080; // Escolha a porta desejada, por exemplo, 3000
app.get("/", (req, res) => {
res.send("Hello, World from Node.js!");
});
app.listen(port, () => {
console.log(`Running: http://localhost:${port}`);
});
Para realizar o benchmark, utilizaremos a ferramenta Apache Benchmark (ab) para fazer 100.000 requisições a cada API e mediremos o tempo médio de resposta. O comando de benchmark será o mesmo para todas as linguagens:
ab -n 100000 -c 10 http://127.0.0.1:8080/
Após a execução do benchmark, obtivemos os seguintes resultados:
Rust com Actix:
Go com Std:
Python com FastAPI:
Python com Sanic:
Java com Quarkus:
Node.js com Express:
Nesse teste simples realizado, com esses parâmetros e códigos, Rust é muito mais rápido que as outras. No repositório estão os códigos utilizados e os resultados com mais detalhes do teste no arquivo result.txt que está nos projetos.