As instruções switch são geralmente mais rápidas do que as instruções if-else-if equivalentes (como, por exemplo, descrito neste artigo ) devido às otimizações do compilador.
Como essa otimização realmente funciona? Alguém tem uma boa explicação?
c#
performance
switch-statement
if-statement
Dirk Vollmar
fonte
fonte
Respostas:
O compilador pode construir tabelas de salto onde aplicável. Por exemplo, ao usar o refletor para examinar o código produzido, você verá que, para grandes interruptores em strings, o compilador irá gerar um código que usa uma tabela hash para despachá-los. A tabela de hash usa as strings como chaves e delega os
case
códigos como valores.Isso tem melhor tempo de execução assintótico do que muitos
if
testes encadeados e é realmente mais rápido mesmo para relativamente poucas strings.fonte
Esta é uma pequena simplificação, pois normalmente qualquer compilador moderno que encontra uma
if..else if ..
sequência que poderia ser convertida trivialmente em uma instrução switch por uma pessoa, o compilador também o fará. Mas apenas para adicionar diversão extra, o compilador não é restrito pela sintaxe, portanto, pode gerar internamente "switch" como declarações que possuem uma mistura de intervalos, alvos únicos, etc - e eles podem (e fazem) fazer isso para switch e if. .outras declarações.De qualquer forma, uma extensão da resposta de Konrad é que o compilador pode gerar uma tabela de salto, mas isso não é necessariamente garantido (nem desejável). Por uma variedade de razões, as tabelas de salto fazem coisas ruins para os preditores de ramificação nos processadores modernos, e as próprias tabelas fazem coisas ruins para o comportamento do cache, por exemplo.
Se um compilador realmente gerasse uma tabela de salto para isso, provavelmente seria mais lento que o
if..else if..
código de estilo alternativo por causa da tabela de salto derrotando a previsão de ramificação.fonte
As estatísticas de no-match podem não ser boas.
Se você realmente fizer o download da fonte, os valores sem correspondência são conhecidos como 21, em ambos os casos, if e switch. Um compilador deve ser capaz de abstrair, sabendo qual instrução deve ser executada o tempo todo, e uma CPU deve ser capaz de fazer previsões de ramificações corretamente.
O caso mais interessante é quando nem todos os casos quebram, em minha opinião, mas esse pode não ter sido o escopo do experimento.
fonte
As instruções switch / case podem ser tipicamente mais rápidas de nível 1, mas quando você começa a usar 2 ou mais, as instruções switch / case levam 2 a 3 vezes mais tempo do que as instruções if / else aninhadas.
Este artigo apresenta algumas comparações de velocidade destacando as diferenças de velocidade quando tais instruções são aninhadas.
Por exemplo, de acordo com seus testes, código de amostra como o seguinte:
terminou na metade do tempo que a instrução switch / case equivalente levou para ser executada:
Sim, é um exemplo rudimentar, mas ilustra o ponto.
Portanto, uma conclusão pode ser usar switch / case para tipos simples que têm apenas um nível de profundidade, mas para comparações mais complexas e vários níveis aninhados, use as construções if / else clássicas?
fonte
A única vantagem do caso if over é quando há um aumento perceptível da frequência de ocorrência do primeiro caso.
Não tenho certeza de onde está o limite, mas uso a sintaxe de caso, a menos que o primeiro "quase sempre" passe no primeiro teste.
fonte