Eu tenho um buffer de string de cerca de 2.000 caracteres e preciso verificar se ele contém uma string específica.
Fará a verificação em um webapp ASP.NET 2.0 para cada webrequest.
Alguém sabe se o método String.Contains tem melhor desempenho do que o método String.IndexOf ?
// 2000 characters in s1, search token in s2
string s1 = "Many characters. The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2);
int i;
i = s1.IndexOf(s2);
Respostas:
Contains
ligaçõesIndexOf
:Que chama
CompareInfo.IndexOf
, que em última análise usa uma implementação CLR.Se você quiser ver como as strings são comparadas no CLR, isso mostrará a você (procure por CaseInsensitiveCompHelper ).
IndexOf(string)
não tem opções eContains()
usa uma comparação Ordinal (uma comparação byte a byte em vez de tentar realizar uma comparação inteligente, por exemplo, e com é).Portanto,
IndexOf
será um pouco mais rápido (em teoria), poisIndexOf
vai direto para uma pesquisa de string usando FindNLSString de kernel32.dll (o poder do refletor!).Atualizado para .NET 4.0 - IndexOf não usa mais comparação ordinal e, portanto, Contains pode ser mais rápido. Veja o comentário abaixo.
fonte
IndexOf()
realmente usaStringComparison.CurrentCulture
eContains()
usa oStringComparison.Ordinal
que será mais rápido. Mas, na verdade, as diferenças de velocidade de que estamos falando são mínimas - a questão é que um chama o outro, e Contém é mais legível se você não precisar do índice. Em outras palavras, não se preocupe com isso.Provavelmente, não fará diferença alguma. Leia esta postagem sobre Coding Horror;): http://www.codinghorror.com/blog/archives/001218.html
fonte
Contains (s2) é muitas vezes (no meu computador 10 vezes) mais rápido que IndexOf (s2) porque Contains usa StringComparison.Ordinal que é mais rápido do que a pesquisa sensível à cultura que IndexOf faz por padrão (mas que pode mudar em .net 4.0 http: //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx ).
Contains tem exatamente o mesmo desempenho que IndexOf (s2, StringComparison.Ordinal)> = 0 em meus testes, mas é mais curto e deixa sua intenção clara.
fonte
Estou executando um caso real (em oposição a um benchmark sintético)
versus
É uma parte vital do meu sistema e é executado 131.953 vezes (obrigado DotTrace).
Por mais chocante surpresa , o resultado é o oposto do esperado
: - /
net framework 4.0 (atualizado em 13-02-2012)
fonte
INT
é muito maior do queBOOL
eIndexOf>=0
causa mais uma etapaUsando o Reflector, você pode ver que o Contains é implementado usando o IndexOf. Aqui está a implementação.
Portanto, o Contains é provavelmente um pouco mais lento do que chamar IndexOf diretamente, mas duvido que tenha qualquer significado para o desempenho real.
fonte
Se você realmente deseja otimizar seu código, sua melhor abordagem é sempre o benchmarking.
A estrutura .net tem uma excelente implementação de cronômetro - System.Diagnostics.Stopwatch
fonte
Com uma pequena leitura, parece que nos bastidores o método String.Contains simplesmente chama String.IndexOf. A diferença é String.Contains retorna um booleano enquanto String.IndexOf retorna um número inteiro com (-1) representando que a substring não foi encontrada.
Eu sugeriria escrever um pequeno teste com 100.000 ou mais iterações e ver por si mesmo. Se eu fosse adivinhar, diria que IndexOf pode ser um pouco mais rápido, mas como disse, é apenas um palpite.
Jeff Atwood tem um bom artigo sobre cordas em seu blog . É mais sobre concatenação, mas pode ser útil mesmo assim.
fonte
Como uma atualização para isso, estou fazendo alguns testes e fornecendo sua string de entrada é bastante grande, então Regex paralelo é o método C # mais rápido que encontrei (desde que você tenha mais de um núcleo, eu imagino)
Obtendo a quantidade total de correspondências, por exemplo -
Espero que isto ajude!
fonte
Use uma biblioteca de referência, como esta recente incursão de Jon Skeet para medi-la.
Caveat Emptor
Como todas as questões de (micro) desempenho, isso depende das versões do software que você está usando, dos detalhes dos dados inspecionados e do código que envolve a chamada.
Como todas as questões de (micro) desempenho, o primeiro passo deve ser obter uma versão em execução que seja de fácil manutenção. Em seguida, benchmarking, criação de perfil e ajuste podem ser aplicados aos gargalos medidos em vez de adivinhação.
fonte
Para quem ainda está lendo isso, indexOf () provavelmente terá um desempenho melhor na maioria dos sistemas corporativos, pois contains () não é compatível com o IE!
fonte