Por que strpos() é mais rápido que KMP em PHP?
Entenda por que algoritmos nativos em C superam implementações complexas em userland e quando usar cada um.
🚀 Native vs Userland: O Caso do strpos()
Ao estudar algoritmos como KMP ou Boyer-Moore, é comum pensar: "Vou implementar isso no meu projeto para deixar a busca de strings super rápida!".
Mas ao fazer um benchmark em PHP, você descobre algo chocante: a função nativa strpos() é muito mais rápida que sua implementação otimizada do KMP. Por que?
🏎️ O Motor por Baixo do Capô
O PHP é escrito em C. Quando você chama strpos(), você não está executando código PHP interpretado; você está acionando uma função em C altamente otimizada que roda diretamente no processador.
Vantagens do Nativo (C):
- Instruções SIMD: Compiladores C modernos usam instruções do processador (como SSE/AVX) para comparar múltiplos bytes de uma só vez.
- Sem Overhead de VM: Não há a camada de interpretação da Zend Engine para cada caractere do loop.
- Algoritmos Híbridos: A implementação interna do PHP (muitas vezes baseada em variantes do Boyer-Moore ou funções da
libccomomemchr) escolhe a melhor estratégia baseada no tamanho da string.
📊 O Benchmark (Conceitual)
Imagine buscar uma palavra em um texto de 1MB.
- KMP em PHP: O interpretador precisa processar o loop
while, acessar o array$lps, comparar caracteres, gerenciar variáveis... tudo isso tem um custo (overhead) por operação. - strpos(): O PHP apenas passa o ponteiro da memória para o C, que "voa" pelos bytes.
<?php
$texto = str_repeat("a", 1000000) . "b";
$padrao = "b";
// KMP (Userland)
// ~0.050 segundos (exemplo)
// strpos (Nativo)
// ~0.0002 segundos (exemplo)
A diferença pode ser de 100x ou mais.
💡 Então, para que aprender KMP?
Se strpos é tão bom, o KMP é inútil? Não!
Use KMP (ou Rabin-Karp) quando:
- Streams: Você não tem a string inteira na memória (ex: lendo de um socket ou arquivo gigante byte a byte).
strposexige a string carregada. - Múltiplos Padrões: Se você precisa buscar 1000 palavras diferentes ao mesmo tempo (Aho-Corasick é melhor aqui, mas a lógica deriva desses algoritmos).
- Lógica Customizada: Se você precisa de uma busca que ignore maiúsculas/minúsculas de um jeito que
striposnão resolve, ou que lide com wildcards complexos.
🏁 Conclusão
- Para 99% dos casos web: Use
strpos(). É O(N) na prática e imbatível em velocidade. - Para entrevistas e streams: Aprenda KMP.