Introdução
Python e Rust ocupam extremos opostos do espectro de linguagens de programação. Python é a linguagem mais popular do mundo em 2026, dominando áreas como ciência de dados, machine learning, automação e desenvolvimento web rápido. Rust é uma linguagem de sistemas focada em performance e segurança, cada vez mais usada para reescrever componentes críticos que antes seriam feitos em C ou C++.
A pergunta não é realmente “qual é melhor?” — cada uma brilha em contextos completamente diferentes. Este artigo vai ajudá-lo a entender quando faz sentido usar Python, quando usar Rust e, mais importante, como combinar as duas com ferramentas como PyO3.
Se você é um desenvolvedor Python curioso sobre Rust, ou um rustacean querendo entender o ecossistema Python, este guia é para você.
Tabela Comparativa
| Aspecto | Rust | Python |
|---|---|---|
| Paradigma | Multi-paradigma (funcional, imperativo) | Multi-paradigma (OOP, funcional, imperativo) |
| Tipagem | Estática, forte, em tempo de compilação | Dinâmica, forte (duck typing) |
| Performance | Próxima de C (compilada, LLVM) | 10-100x mais lenta (interpretada, GIL) |
| Gerenciamento de memória | Ownership + Borrow Checker | Garbage Collector + Reference Counting |
| Concorrência | Threads reais + async/await | GIL limita threads; asyncio para I/O |
| Curva de aprendizado | Íngreme (ownership, lifetimes, tipos) | Muito suave (pseudocódigo executável) |
| Ecossistema | crates.io (~150k crates) | PyPI (~500k pacotes) |
| Uso principal | Sistemas, CLI, WebAssembly, infraestrutura | Data science, ML, web, automação, scripts |
| REPL | Não oficial (evcxr) | Excelente (IPython, Jupyter) |
| Tempo de desenvolvimento | Mais lento (compilação + tipos) | Muito rápido (prototipagem ágil) |
Exemplos de Código: Processamento de Dados
Vamos comparar uma tarefa comum: ler um arquivo CSV, filtrar registros e calcular uma média.
Python
import csv
from statistics import mean
def processar_vendas(caminho: str) -> dict:
"""Lê CSV de vendas e retorna estatísticas por região."""
vendas_por_regiao: dict[str, list[float]] = {}
with open(caminho, "r", encoding="utf-8") as arquivo:
leitor = csv.DictReader(arquivo)
for linha in leitor:
regiao = linha["regiao"]
valor = float(linha["valor"])
if valor > 0:
vendas_por_regiao.setdefault(regiao, []).append(valor)
return {
regiao: {
"total": sum(valores),
"media": mean(valores),
"quantidade": len(valores),
}
for regiao, valores in vendas_por_regiao.items()
}
resultado = processar_vendas("vendas.csv")
for regiao, stats in resultado.items():
print(f"{regiao}: total={stats['total']:.2f}, média={stats['media']:.2f}")
Rust
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
#[derive(Debug)]
struct Estatisticas {
total: f64,
media: f64,
quantidade: usize,
}
fn processar_vendas(caminho: &str) -> Result<HashMap<String, Estatisticas>, Box<dyn Error>> {
let arquivo = File::open(caminho)?;
let mut leitor = csv::Reader::from_reader(arquivo);
let mut vendas_por_regiao: HashMap<String, Vec<f64>> = HashMap::new();
for resultado in leitor.records() {
let registro = resultado?;
let regiao = registro[1].to_string(); // coluna "regiao"
let valor: f64 = registro[2].parse()?; // coluna "valor"
if valor > 0.0 {
vendas_por_regiao.entry(regiao).or_default().push(valor);
}
}
let estatisticas = vendas_por_regiao
.into_iter()
.map(|(regiao, valores)| {
let total: f64 = valores.iter().sum();
let quantidade = valores.len();
let media = total / quantidade as f64;
(regiao, Estatisticas { total, media, quantidade })
})
.collect();
Ok(estatisticas)
}
fn main() -> Result<(), Box<dyn Error>> {
let resultado = processar_vendas("vendas.csv")?;
for (regiao, stats) in &resultado {
println!("{}: total={:.2}, média={:.2}", regiao, stats.total, stats.media);
}
Ok(())
}
O código Python é mais conciso e legível. O código Rust é mais verboso, mas trata erros explicitamente com Result, não tem overhead de GC e processa o arquivo significativamente mais rápido — especialmente para arquivos grandes.
Para mais exemplos de processamento de dados em Rust, veja nossa receita de parse JSON.
A Diferença de Performance: Por Que 100x?
A diferença de velocidade entre Rust e Python em operações CPU-bound pode chegar a 100x ou mais. Vamos entender o porquê:
Benchmark: Fibonacci Recursivo
# Python
def fib(n: int) -> int:
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# fib(40) em Python: ~25 segundos
// Rust
fn fib(n: u64) -> u64 {
if n <= 1 {
return n;
}
fib(n - 1) + fib(n - 2)
}
// fib(40) em Rust: ~0.25 segundos
Por Que Essa Diferença Existe?
| Fator | Python | Rust |
|---|---|---|
| Interpretação | Bytecode interpretado pelo CPython | Compilado para código de máquina nativo |
| Tipagem dinâmica | Verificação de tipo em runtime a cada operação | Tipos resolvidos em tempo de compilação |
| Boxed integers | Cada int é um objeto no heap | Inteiros ficam em registradores da CPU |
| GIL | Impede paralelismo real em threads | Threads reais com paralelismo total |
| Cache de CPU | Layouts de memória dispersos | Dados contíguos, cache-friendly |
Benchmarks Realistas
| Tarefa | Python | Rust | Speedup |
|---|---|---|---|
| Parse de JSON (1GB) | 45s | 0,8s | ~56x |
| Ordenação (10M números) | 12s | 0,4s | ~30x |
| Regex em arquivo (500MB) | 18s | 0,3s | ~60x |
| Servidor HTTP (req/s) | ~15.000 (uvicorn) | ~850.000 (axum) | ~57x |
| Fibonacci(40) | 25s | 0,25s | ~100x |
Ponte Entre Mundos: PyO3
A melhor parte é que você não precisa escolher. O PyO3 permite escrever extensões Python em Rust, combinando a produtividade do Python com a performance do Rust:
// lib.rs — extensão Python escrita em Rust
use pyo3::prelude::*;
#[pyfunction]
fn soma_rapida(numeros: Vec<f64>) -> f64 {
numeros.iter().sum()
}
#[pyfunction]
fn filtrar_positivos(numeros: Vec<f64>) -> Vec<f64> {
numeros.into_iter().filter(|&n| n > 0.0).collect()
}
#[pymodule]
fn meu_modulo_rust(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(soma_rapida, m)?)?;
m.add_function(wrap_pyfunction!(filtrar_positivos, m)?)?;
Ok(())
}
# Usando a extensão Rust em Python
import meu_modulo_rust
numeros = [1.5, -2.0, 3.7, -0.5, 8.1]
total = meu_modulo_rust.soma_rapida(numeros)
print(f"Soma: {total}") # Soma: 10.8
positivos = meu_modulo_rust.filtrar_positivos(numeros)
print(f"Positivos: {positivos}") # Positivos: [1.5, 3.7, 8.1]
Projetos como Polars (alternativa ao Pandas, 10-100x mais rápido), Pydantic v2 (validação de dados), ruff (linter Python mais rápido do mundo) e uv (gerenciador de pacotes) já usam essa abordagem com sucesso.
Tipagem: Dinâmica vs Estática na Prática
A diferença de tipagem entre Python e Rust vai além de performance. Ela afeta diretamente a experiência de manutenção e refatoração de código.
Python: Type Hints São Opcionais
# Python: type hints não são enforçados em runtime
def calcular_desconto(preco: float, percentual: float) -> float:
return preco * (1 - percentual / 100)
# Isso funciona em runtime, apesar de estar "errado" tipadamente
resultado = calcular_desconto("100", "10") # String, não float!
# TypeError em runtime, não em "compilação"
Python adicionou type hints (PEP 484), e ferramentas como mypy e pyright fazem verificação estática, mas são opcionais. Muitas bibliotecas e projetos legados não têm types, e o ecossistema ainda está em transição.
Rust: Tipos São Obrigatórios e Verificados
fn calcular_desconto(preco: f64, percentual: f64) -> f64 {
preco * (1.0 - percentual / 100.0)
}
fn main() {
let resultado = calcular_desconto(100.0, 10.0);
println!("Preço com desconto: R${resultado:.2}");
// calcular_desconto("100", "10"); // ERRO DE COMPILAÇÃO: tipos incompatíveis
}
Em Rust, o sistema de tipos é obrigatório e verificado em compilação. Isso significa que refatorações em projetos grandes são muito mais seguras — se compila, os tipos estão corretos.
Ferramentas Python Escritas em Rust
Um fenômeno interessante em 2026 é que muitas das ferramentas mais populares do ecossistema Python são escritas em Rust:
- ruff: linter e formatter 10-100x mais rápido que flake8/black
- uv: gerenciador de pacotes Python 10-100x mais rápido que pip
- Polars: biblioteca de DataFrames alternativa ao Pandas, 10-50x mais rápida
- Pydantic v2: core de validação reescrito em Rust, 5-50x mais rápido
- tokenizers (Hugging Face): tokenização de texto para NLP
- cryptography: backend criptográfico seguro
Isso demonstra o padrão que se consolida: Python como interface, Rust como motor de performance.
Quando Usar Python
Escolha Python quando:
- Prototipagem rápida: validar ideias em horas, não dias
- Data Science e Machine Learning: NumPy, Pandas, scikit-learn, PyTorch, TensorFlow
- Automação e scripts: tarefas administrativas, ETL, web scraping
- APIs simples: FastAPI/Django para CRUDs e MVPs
- A equipe é de cientistas de dados: Python é a lingua franca da área
- Jupyter Notebooks: exploração interativa de dados
Quando Usar Rust
Escolha Rust quando:
- Performance é crítica: processamento de dados em larga escala, sistemas de baixa latência
- O gargalo do Python é a CPU: loops intensivos, cálculos numéricos sem NumPy
- Confiabilidade importa: sistemas que não podem crashar, infraestrutura crítica
- Consumo de memória importa: serverless, containers, dispositivos embarcados
- Você precisa de concorrência real: processamento paralelo sem o GIL
- CLIs de alta performance: ferramentas como ripgrep, fd, bat
Quando Combinar os Dois
A abordagem mais inteligente em muitos cenários é usar Python como cola e Rust nos pontos quentes:
- Escreva a lógica de negócios e orquestração em Python
- Profile o código para encontrar gargalos
- Reescreva apenas os gargalos em Rust usando PyO3
- Mantenha a interface Python para o resto da equipe
Essa estratégia é usada por empresas como Dropbox, Discord e Cloudflare.
Conclusão e Recomendação
Para a maioria dos desenvolvedores Python, a recomendação é: continue usando Python como sua linguagem principal, mas aprenda Rust para estender Python quando a performance não for suficiente. A combinação Python + Rust via PyO3 oferece o melhor dos dois mundos.
Se você está começando um projeto novo que é principalmente CPU-bound (compilador, game engine, sistema embarcado, processamento de dados em escala), comece em Rust. O investimento inicial na curva de aprendizado se paga com manutenção mais simples e performance superior.
Não reescreva projetos Python inteiros em Rust a menos que tenha uma razão muito forte. Identifique os 10% do código que causam 90% dos problemas de performance e reescreva apenas esses trechos.
Para começar com Rust vindo do Python, recomendamos nosso tutorial de primeiros passos.
Veja Também
- Primeiros Passos com Rust — Comece aqui se você vem do Python
- Receita: Parse de JSON em Rust — Processamento de dados estruturados
- Rust vs Go: Qual Escolher em 2026 — Outra comparação popular
- Rust vs C++: Segurança sem Sacrificar Performance — Para quem busca mais performance
- Glossário Rust — Termos como ownership, borrowing e lifetimes explicados
- Instalação do Rust — Configure seu ambiente de desenvolvimento