🚀 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):

  1. Instruções SIMD: Compiladores C modernos usam instruções do processador (como SSE/AVX) para comparar múltiplos bytes de uma só vez.
  2. Sem Overhead de VM: Não há a camada de interpretação da Zend Engine para cada caractere do loop.
  3. Algoritmos Híbridos: A implementação interna do PHP (muitas vezes baseada em variantes do Boyer-Moore ou funções da libc como memchr) 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:

  1. Streams: Você não tem a string inteira na memória (ex: lendo de um socket ou arquivo gigante byte a byte). strpos exige a string carregada.
  2. 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).
  3. Lógica Customizada: Se você precisa de uma busca que ignore maiúsculas/minúsculas de um jeito que stripos nã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.