Mas o buraco é um pouco mais embaixo. Enquanto quando as pessoas dizem que python é mais lento que C, querendo dizer de fato que CPython é mais lento que C, esses runtimes novos não são essa panaceia toda. Veja aqui nesse link que alguns construtos não estão implementados (ainda?), como:
- async features:
async with
,async for
easync def
- class definition:
class
(except for@jitclas
) - set, dict and generator comprehensions
- generator delegation:
yield from
Dá para fazer otimizações que, com certeza, são muito úteis, mas está longe de ser uma bala de prata no que diz respeito a desempenho em Python. Quem trabalha com computação científica em Python, se não puder delegar a computação pesada para uma lib em C/C++ (Stan, Pytorch, numpy), ou vai ter que implementar algo no braço, em C/C++/Rust, ou vai ter que combinar isso com essas otimizações.
E aí não dá para não falar do Julia, porque o Julia foi projetado do zero para operar com um REPL (aqui estou pensando em ciência de dados), para trabalhar de forma iterativa, mas também permite definir o tipo das variáveis, e não anotações de tipo, e realmente o Julia compila o código na primeira vez que você roda e daí para frente costuma ter um desempenho próximo ao C. Só que para fazer isso a linguagem foi projetada do zero para conseguir isso, com multiple dispatch dentre outras "mágicas". Creio eu que não seria tão fácil fazer isso com o Python e manter compatibilidade.
O Julia foi tão bem-sucedido nisso que as bibliotecas para computação pesada, como fazer MCMC, deep learning ou manipular data frames, é tudo feito em Julia puro. Claro, tem também uma série de otimizações que você tem que fazer para obter o melhor resultado possível, mas você está fazendo tudo em uma linguagem só.
No caso de Python o que poderia entregar isso é o Mojo, mas aí vamos ver...