aneira mais rápida de remover todos os caracteres não imprimíveis de uma String Ja
Qual é a maneira mais rápida de remover todos os caracteres não imprimíveis de umString
em Java?
té agora, tentei e medi-lo na sequência de 138 bytes e 131 caracteres:
CordasreplaceAll()
- slowest method 517009 resultados / sCompile um padrão e use o Matcher'sreplaceAll()
637836 resultados / sUse StringBuffer, obtenha pontos de código usandocodepointAt()
um por um e acrescente a StringBuffer 711946 resultados / sUse StringBuffer, obtenha caracteres usandocharAt()
um por um e acrescente a StringBuffer 1052964 resultados / sPreallocate achar[]
buffer, obtenha caracteres usandocharAt()
um por um e preencha esse buffer e depois converta novamente em String 2022653 resultados / sPreallocate 2char[]
buffers - antigos e novos, obtenha todos os caracteres da String existente de uma só vez usandogetChars()
, repita um a um o buffer antigo, preencha um novo buffer e converta o novo buffer em String - minha própria versão mais rápida 2502502 resultados / s Coisas iguais com 2 buffers - apenas usandobyte[]
, getBytes()
e especificando a codificação como "utf-8" 857485 resultados / sMinhas coisas com 2byte[]
buffers, mas especificando a codificação como uma constanteCharset.forName("utf-8")
791076 resultados / sMinhas coisas com 2byte[]
buffers, mas especificando a codificação como codificação local de 1 byte (quase uma coisa sã de se faze 370164 resultados / sMinha melhor tentativa foi a seguinte:
char[] oldChars = new char[s.length()];
s.getChars(0, s.length(), oldChars, 0);
char[] newChars = new char[s.length()];
int newLen = 0;
for (int j = 0; j < s.length(); j++) {
char ch = oldChars[j];
if (ch >= ' ') {
newChars[newLen] = ch;
newLen++;
}
}
s = new String(newChars, 0, newLen);
Alguma idéia de como torná-lo ainda mais rápid
@ Bonus aponta para responder a uma pergunta muito estranha: por que usar o nome do conjunto de caracteres "utf-8" gera melhor desempenho diretamente do que usar const estático pré-alocadCharset.forName("utf-8")
?
Eu tentei o meu melhor para coletar todas as soluções propostas e suas mutações cruzadas e as publiquei como umsmall framework de benchmarking no github. Atualmente, possui 17 algoritmos. Um deles é "especial" - Voo1 algoritmo fornecido pelo usuário SO Voo) emprega truques intrincados de reflexão, alcançando velocidades estelares, mas atrapalha o estado das cadeias de caracteres da JVM, portanto é comparado separadament
Você pode verificar e executá-lo para determinar os resultados em sua caixa. Aqui está um resumo dos resultados que tenho nos meus. É especificações:
Debian sidLinux 2.6.39-2-amd64 (x86_64) Java instalado a partir de um pacotesun-java6-jdk-6.24-1
, A JVM se identifica comoJava (TM) SE Runtime Environment (compilação 1.6.0_24-b07)M do servidor Java de 64 bits do HotSpot (TM) (build 19.1-b02, modo misto)s algoritmos do @Different mostram resultados diferentes, considerando um conjunto diferente de dados de entrada. Corri uma referência em três modos:
Same string únicaEste modo funciona em uma mesma string única fornecida porStringSource
classe como uma constante. O confronto é:
Ops / s │ Algorithm ──────────┼────────────────────────────── 6 535 947 │ Voo1 ──────────┼────────────────────────────── 5 350 454 │ RatchetFreak2EdStaub1GreyCat1 5 249 343 │ EdStaub1 5 002 501 │ EdStaub1GreyCat1 4 859 086 │ ArrayOfCharFromStringCharAt 4 295 532 │ RatchetFreak1 4 045 307 │ ArrayOfCharFromArrayOfChar 2 790 178 │ RatchetFreak2EdStaub1GreyCat2 2 583 311 │ RatchetFreak2 1 274 859 │ StringBuilderChar 1 138 174 │ StringBuilderCodePoint 994 727 │ ArrayOfByteUTF8String 918 611 │ ArrayOfByteUTF8Const 756 086 │ MatcherReplace 598 945 │ StringReplaceAll 460 045 │ ArrayOfByteWindows1251
Em forma de gráfico:Same chart single string http://www.greycat.ru/img/os-chart-single.pn
Múltiplas cadeias, 100% das cadeias contêm caracteres de controleprovedor de fontes @Source pré-gerou muitas seqüências aleatórias usando o conjunto de caracteres (0..127) - portanto, quase todas as seqüências continham pelo menos um caractere de controle. Os algoritmos receberam seqüências de caracteres dessa matriz pré-gerada de maneira round-robi
Ops / s │ Algorithm ──────────┼────────────────────────────── 2 123 142 │ Voo1 ──────────┼────────────────────────────── 1 782 214 │ EdStaub1 1 776 199 │ EdStaub1GreyCat1 1 694 628 │ ArrayOfCharFromStringCharAt 1 481 481 │ ArrayOfCharFromArrayOfChar 1 460 067 │ RatchetFreak2EdStaub1GreyCat1 1 438 435 │ RatchetFreak2EdStaub1GreyCat2 1 366 494 │ RatchetFreak2 1 349 710 │ RatchetFreak1 893 176 │ ArrayOfByteUTF8String 817 127 │ ArrayOfByteUTF8Const 778 089 │ StringBuilderChar 734 754 │ StringBuilderCodePoint 377 829 │ ArrayOfByteWindows1251 224 140 │ MatcherReplace 211 104 │ StringReplaceAll
Em forma de gráfico:Várias strings, 100% de concentração http://www.greycat.ru/img/os-chart-multi100.pn
Várias strings, 1% das strings contêm caracteres de controleIgual ao anterior, mas apenas 1% das strings foram geradas com caracteres de controle - outros 99% foram gerados usando o conjunto de caracteres [32..127], para que não pudessem conter caracteres de controle. Essa carga sintética é a mais próxima da aplicação real desse algoritmo na minha casa.
Ops / s │ Algorithm ──────────┼────────────────────────────── 3 711 952 │ Voo1 ──────────┼────────────────────────────── 2 851 440 │ EdStaub1GreyCat1 2 455 796 │ EdStaub1 2 426 007 │ ArrayOfCharFromStringCharAt 2 347 969 │ RatchetFreak2EdStaub1GreyCat2 2 242 152 │ RatchetFreak1 2 171 553 │ ArrayOfCharFromArrayOfChar 1 922 707 │ RatchetFreak2EdStaub1GreyCat1 1 857 010 │ RatchetFreak2 1 023 751 │ ArrayOfByteUTF8String 939 055 │ StringBuilderChar 907 194 │ ArrayOfByteUTF8Const 841 963 │ StringBuilderCodePoint 606 465 │ MatcherReplace 501 555 │ StringReplaceAll 381 185 │ ArrayOfByteWindows1251
Em forma de gráfico:Várias strings, 1% de concentração http://www.greycat.ru/img/os-chart-multi1.pn
É muito difícil para mim decidir quem forneceu a melhor resposta, mas, como a aplicação do mundo real foi a melhor solução dada / inspirada por Ed Staub, acho que seria justo marcar sua resposta. Obrigado por todos que participaram, sua contribuição foi muito útil e inestimável. Sinta-se à vontade para executar o conjunto de testes em sua caixa e propor soluções ainda melhores (solução JNI funcionando, alguém?).
Referênciaepositório @ GitHub com um conjunto de benchmarking