Há muitos motivos que podem ser considerados para a escolha de um idioma X em detrimento de um idioma Y. Legibilidade do programa, facilidade de programação, portabilidade para muitas plataformas, existência de bons ambientes de programação podem ser esses motivos. No entanto, considerarei apenas a velocidade de execução, conforme solicitado na pergunta. A questão não parece considerar, por exemplo, a velocidade do desenvolvimento.
Dois idiomas podem ser compilados no mesmo código de bytes, mas isso não significa que o mesmo código será produzido,
Na verdade, bytecode é apenas código para uma máquina virtual específica. Ele possui vantagens de engenharia, mas não apresenta diferenças fundamentais na compilação direta de um harware específico. Portanto, você também pode comparar duas linguagens compiladas para execução direta na mesma máquina.
Dito isto, a questão da velocidade relativa das linguagens é antiga, datando dos primeiros compiladores.
Por muitos anos, naqueles primeiros tempos, o profissional considerou que o código escrito à mão era mais rápido que o código compilado. Em outras palavras, a linguagem de máquina foi considerada mais rápida que as linguagens de alto nível, como Cobol ou Fortran. E era mais rápido e geralmente menor. As linguagens de alto nível ainda se desenvolveram porque eram muito mais fáceis de usar para muitas pessoas que não eram cientistas da computação. O custo do uso de linguagens de alto nível tinha até um nome: a taxa de expansão, que poderia dizer respeito ao tamanho do código gerado (uma questão muito importante naqueles tempos) ou ao número de instruções realmente executadas. O conceito era principalmente experimental, mas a proporção era superior a 1 no início, já que os compiladores fizeram um trabalho bastante simples pelos padrões atuais.
Assim, a linguagem de máquina era mais rápida do que o Fortran.
Obviamente, isso mudou ao longo dos anos, à medida que os compiladores se tornaram mais sofisticados, a ponto de que a programação em linguagem assembly agora é muito rara. Para a maioria dos aplicativos, os programas em linguagem assembly competem mal com o código gerado pela otimização de compiladores.
Isso mostra que uma questão importante é a qualidade dos compiladores disponíveis para o idioma considerado, sua capacidade de analisar o código fonte e otimizá-lo de acordo.
Essa capacidade pode depender, em certa medida, dos recursos da linguagem para enfatizar as propriedades estruturais e matemáticas da fonte, a fim de facilitar o trabalho do compilador. Por exemplo, uma linguagem pode permitir a inclusão de instruções sobre as propriedades algébricas de funções definidas pelo usuário, de modo a permitir que o compilador use essas propriedades para fins de otimização.
O processo de compilação pode ser mais fácil, produzindo um código melhor, quando o paradigma de programação da linguagem estiver mais próximo dos recursos das máquinas que interpretarão o código, seja ela real ou virtual.
Outro ponto é se os paradigmas implementados na linguagem estão fechados para o tipo de problema que está sendo programado. É de se esperar que uma linguagem de programação especializada para paradigmas de programação específicos compile de maneira muito eficiente os recursos relacionados a esse paradigma. Portanto, a escolha de uma linguagem de programação pode depender, para maior clareza e rapidez, da escolha de uma linguagem de programação adaptada ao tipo de problema que está sendo programado.
A popularidade de C para programação de sistemas provavelmente se deve ao fato de que C está próximo da arquitetura da máquina e que a programação do sistema também está diretamente relacionada a essa arquitetura.
Algum outro problema será mais facilmente programado, com execução mais rápida usando programação lógica e linguagens de resolução de restrições .
Sistemas reativos complexos podem ser programados de maneira muito eficiente com linguagens de programação síncrona especializadas, como a Esterel, que incorpora conhecimento muito especializado sobre esses sistemas e gera código muito rápido.
Ou, para dar um exemplo extremo, algumas linguagens são altamente especializadas, como linguagens de descrição de sintaxe usadas para programar analisadores. Um gerador de analisador nada mais é do que um compilador para essas linguagens. Obviamente, o Turing não é completo, mas esses compiladores são extremamente bons para sua especialidade: produzir programas de análise eficientes. Sendo o domínio do conhecimento restrito, as técnicas de otimização podem ser muito especializadas e ajustadas com muito cuidado. Esses geradores de analisador geralmente são muito melhores do que o que poderia ser obtido escrevendo código em outro idioma. Existem muitas linguagens altamente especializadas com compiladores que produzem código excelente e rápido para uma classe restrita de problemas.
Portanto, ao escrever um sistema grande, pode ser aconselhável não confiar em um único idioma, mas escolher o melhor idioma para diferentes componentes do sistema. Isso, é claro, levanta problemas de compatibilidade.
Outro ponto que importa frequentemente é simplesmente a existência de bibliotecas eficientes para os tópicos que estão sendo programados.
Finalmente, a velocidade não é o único critério e pode estar em conflito com outros critérios, como segurança de código (por exemplo, com relação a entradas incorretas ou resiliência a erros do sistema), uso de memória, facilidade de programação (embora a compatibilidade de paradigmas possa realmente ajudar a ), tamanho do código do objeto, manutenção do programa etc.
A velocidade nem sempre é o parâmetro mais importante. Além disso, pode assumir diferentes formas, como complexidade, que pode ser complexidade média ou, no pior caso, complexidade. Além disso, em um sistema grande como em um programa menor, há partes em que a velocidade é crítica e outras em que pouco importa. E nem sempre é fácil determinar isso com antecedência.