Pergunta

Eu estou usando extensivamente estruturas de dados de mapa de hash no meu programa. Eu estou usando uma implementação de mapa de hash por Barry Kelly postou nos fóruns CodeGear. Essa implementação usa internamente função CompareText da RTL. Profiling me fez perceber que um monte de tempo é gasto na função SysUtils CompareText.

Eu tinha um olhar para o

Fastcode local

e encontrou algumas implementações mais rápidas de CompareText. Infelizmente, eles não parecem trabalhar para D2009 e suas cadeias de caracteres Unicode.

Agora, a pergunta: Existe uma versão mais rápida similar que cordas suportes D2009? As funções CompareText parece ser chamado de um monte ao usar mapas hash (pelo menos no implemenation Eu estou usando atualmente), tão pouco melhorias de desempenho poderia realmente fazer a diferença. Ou se as implementações apresentado há também trabalho para strings unicode?

Foi útil?

Solução

Muitas das funções FastCode provavelmente irá compilar e parecem funcionar muito bem em Delphi 2009, mas não vai ser bom para todas as entradas. Os que são implementadas em assembler irá falhar porque eles assumem personagens são apenas um byte cada. Os implementados em Delphi irá tarifa um pouco melhor, mas ainda vai retornar resultados incorretos, por vezes, porque noção do velho CompareText de "case-insensitive" é baseado em ASCII Considerando que o novo deve ser baseado em Unicode. As regras para o qual os caracteres são considerados o mesmo save para o caso são muito diferente para Unicode de como eles são para ASCII.

Andreas diz em um comentário abaixo que Unicode CompareText ainda usa as regras caso a comparação ASCII, então uma série de funções FastCode deve funcionar bem. Basta olhar-los antes de usá-los para se certificar de que eles não estão fazendo suposições personagem-size. Eu me lembro que alguns funções FastCode foram incorporados ao Delphi RTL já. Eu não tenho idéia se CompareText era um deles.

Se você está chamando CompareText um monte em uma tabela hash, então isso sugere sua tabela hash não está fazendo um trabalho muito bom. CompareText só deve ter chamado quando o hash da coisa que você está procurando designado um balde não vazio na tabela de hash. A partir daí, uma tabela hash, muitas vezes, usar uma pesquisa linear para encontrar o item certo no balde, e ele irá chamar CompareText para cada item durante essa pesquisa. Eu não sei se isso é como esse que você está usando funciona.

Você pode resolver isso usando uma função hash diferente, que distribui seus resultados de forma mais uniforme ao longo dos baldes disponíveis. Se os seus baldes já estão uniformemente preenchido, então você pode precisar de mais baldes (e certifique-se a função hash ainda distribui uniformemente sobre que número bem).

Se a classe de hash-mapa que você está usando é baseado em TBucketList, então há espaço para melhorias no armazenamento balde. Essa classe não calcula um hash em toda a entrada. Ele usa a entrada única para determinar o balde para uso. Se a classe também acompanhar o hash completo calculado para uma string, então as comparações durante a busca linear poderia ir muito mais rápido. Basta comparar os hashes, e só comparar as cordas quando os hashes corresponder completamente. (Para uma lista balde-256-balde, o tamanho maior suportado, somente um byte de entrada determina o balde, e o resto dos bytes são ignorados.) Eu escrevi sobre TBucketList aqui antes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top