Quantas linhas de C são necessárias para executar um + b em Python
A expressão simples `a + b` em Python esconde uma grande quantidade de código em C e maquinaria de runtime, desde dispatch dinâmico e métodos mágicos até inteiros de precisão arbitrária e busca de atributos baseada em hash. Os comentaristas usam isso como ponto de partida para examinar por que o CPython é relativamente lento em comparação com runtimes baseados em JIT (como V8, LuaJIT ou PyPy), apontando escolhas de design como dinamismo onipresente de objetos, a API C e hashing orientado à segurança. Muitos argumentam que o Python se destaca como “cola” em torno de bibliotecas rápidas em C ou C++, em vez de como um motor de computação de alto desempenho, e que ganhos substanciais de velocidade exigiriam mudanças arquitetônicas profundas, não apenas ajustes superficiais.
Escopo da pergunta original
- Muitos observam que o artigo na verdade não responde “quantas linhas de C” são executadas para
a + b. - Vários argumentam que a noção é mal formulada: uma vez que você permite sobrecarga de operador (
__add__/__radd__),a + bpode realizar trabalho arbitrariamente complexo. - Outros sugerem que, no mínimo, seria possível medir uma execução concreta usando cobertura de código ou profiling, mas mesmo isso depende do caminho seguido e da entrada.
Dispatch dinâmico, métodos mágicos e complexidade
- A discussão enfatiza quanta maquinaria existe por trás até das operações mais simples no CPython: modelo de objetos, dispatch dinâmico via slots de tipo, métodos mágicos
__dunder__, descriptors e exceções para iteração. - Comparado a linguagens como JS ou Lua, o Python expõe “mágica” de forma mais abrangente em objetos comuns, o que torna mais difícil fazer otimizações agressivas e JITing.
- Subclassificar builtins (por exemplo,
int) e descriptors personalizados complicam ainda mais a especialização.
Desempenho, JITs e trade-offs de design
- Vários comentaristas argumentam que o CPython não é intencionalmente focado em desempenho; ele otimiza para simplicidade e interoperabilidade com C, e o Python é melhor visto como “cola” sobre bibliotecas nativas rápidas.
- Outros contrapõem que outras linguagens dinâmicas (JS, LuaJIT, Smalltalk, JITs de Ruby) mostram que alto desempenho é possível com engenharia suficiente.
- Há debate sobre se o design da linguagem Python ou a API C e o ecossistema são os principais obstáculos para um JIT de primeira linha.
- Trabalhos recentes para tornar o CPython mais rápido e JITs externos (PyPy, Pyston) são mencionados; as melhorias até agora são vistas como reais, mas modestas em comparação com a revolução dos JITs em JS.
Hashing, segurança e velocidade
- Um fio lateral revisita alegações de que mudar a função de hash do Python poderia dobrar o desempenho.
- Vários comentaristas contestam isso: hashes de strings são armazenados em cache, nomes de símbolos são internados, e benchmarks que mostravam ganhos enormes foram criticados como irreais.
- O SipHash aleatorizado do Python (em vez do antigo FNV) existe principalmente para resistência a HashDoS; o impacto no desempenho em workloads reais parece pequeno.
- Discute-se o hashing por identidade para inteiros; ele interage com a implementação de tabelas de hash e pode causar patologias com certas distribuições de inteiros.
Ergonomia de C vs Python e “é só usar C”
- Alguns sugerem que pode ser “mais fácil” usar C diretamente, mas outros ressaltam o boilerplate drasticamente menor do Python e o suporte embutido a inteiros de precisão arbitrária.
- Exemplos destacam quantas poucas linhas de Python implementam aritmética de precisão arbitrária em comparação com as muitas linhas de C ou C++ necessárias para igualar comportamento e segurança.