A JVM atual tem dois tipos de códigos de byte de switch: LookupSwitch e TableSwitch.
Cada caso em uma instrução switch tem um deslocamento inteiro, se esses deslocamentos são contíguos (ou principalmente contíguos sem grandes lacunas) (caso 0: caso 1: caso 2, etc.), então TableSwitch é usado.
Se os deslocamentos estiverem espalhados com grandes lacunas (caso 0: caso 400: caso 93748 :, etc.), então LookupSwitch é usado.
A diferença, em resumo, é que TableSwitch é feito em tempo constante porque cada valor dentro da faixa de valores possíveis recebe um deslocamento de código de byte específico. Portanto, quando você atribui à instrução um deslocamento de 3, ela sabe pular 3 para encontrar o branch correto.
O switch de pesquisa usa uma pesquisa binária para encontrar a ramificação de código correta. Isso é executado em tempo O (log n), que ainda é bom, mas não é o melhor.
Para obter mais informações sobre isso, consulte aqui: Diferença entre LookupSwitch e TableSwitch da JVM?
Portanto, quanto a qual é o mais rápido, use esta abordagem: Se você tiver 3 ou mais casos cujos valores são consecutivos ou quase consecutivos, sempre use um switch.
Se você tiver 2 casos, use uma instrução if.
Para qualquer outra situação, a troca é provavelmente mais rápida, mas não é garantida, uma vez que a pesquisa binária em LookupSwitch pode atingir um cenário ruim.
Além disso, lembre-se de que a JVM executará otimizações JIT nas instruções if que tentarão colocar primeiro o branch mais ativo no código. Isso é chamado de "Previsão de Branch". Para obter mais informações sobre isso, consulte aqui: https://dzone.com/articles/branch-prediction-in-java
Suas experiências podem variar. Não sei se a JVM não executa uma otimização semelhante no LookupSwitch, mas aprendi a confiar nas otimizações JIT e a não tentar ser mais esperto que o compilador.