Pergunta

Eu fui informado de que a minha biblioteca é mais lento do que deveria ser, na ordem de 30 vezes demasiado lento análise de um determinado arquivo (arquivo de texto, tamanho: 326 kb).O usuário sugeriu que a mesma pode ser que eu estou usando std::ifstream (presumivelmente em vez de FILE).

Eu prefiro não cegamente, reescrever, então eu pensei que eu iria verificar aqui, pois meu palpite seria o gargalo está em outro lugar.Estou a ler caractere por caractere, portanto, as únicas funções que eu estou usando são get(), peek(), e tellg()/seekg().

Atualização:

Eu perfilado, e tem confuso saída - o gprof não parecem pensar que ele demorou tanto.Eu reescreveu o programa para ler o arquivo inteiro em um buffer primeiro, e é acelerado por cerca de 100x.Eu acho que o problema pode ter sido o tellg()/seekg() que teve um longo tempo, mas o gprof pode ter sido incapaz de ver que, por algum motivo.Em qualquer caso, ifstream não não aparecer buffer para o arquivo inteiro, mesmo para este tamanho.

Foi útil?

Solução

Eu não acho que isso faria diferença. Especialmente se você está lendo char por char, é provável que a sobrecarga de E/S domine completamente nada senão. Por que você lê bytes únicos por vez? Você sabe o quão extremamente ineficiente é?

Em um arquivo de 326kb, a solução mais rápida provavelmente será apenas lê -lo na memória de uma só vez.

A diferença entre o std :: ifstream e os equivalentes C é basicamente uma chamada de função virtual ou duas. Pode fazer a diferença se executar algumas dezenas de milhões de vezes por segundo, caso contrário, não realll. A E/S de arquivo geralmente é tão lenta que a API usada para acessar não importa. O que importa muito mais é o padrão de leitura/gravação. Muitas busca são ruins, leituras/gravações sequenciais.

Outras dicas

Deve ser um pouco mais lento, mas, como o que você disse, pode não ser o gargalo. Por que você não perfura seu programa e vê se é esse o caso?

Eu acho que é improvável que o seu problema será corrigido pela troca do fstream para ARQUIVO*, geralmente ambos são armazenados pela biblioteca C.Também o sistema operacional pode armazenar em cache lê (o linux é muito bom nesse aspecto).Dado o tamanho do arquivo que você está acessando é muito provável que ele será inteiramente na memória RAM.

Como PolyThinker dizer que sua melhor aposta é a de executar o programa através de uma profiler um determinar onde está o problema.

Você também estiver usando seekg/tellg isto pode causar notáveis atrasos se o seu disco é muito fragmentado, porque para ler o arquivo pela primeira vez, o disco tem que se mover a cabeça para a posição correta.

Todos os benchmarks são maus. Basta perfil do seu código para os dados que você espera.

Realizei uma comparação de desempenho de E/S entre Ruby, Python, Perl, C ++ uma vez. Para meus dados, versões de idiomas, a variante de C ++ foi várias vezes mais lenta (era uma grande surpresa na época).

Eu concordo que você deve perfil. Mas se você estiver lendo o arquivo de um personagem de cada vez, que tal criar um arquivo mapeado de memória? Dessa forma, você pode tratar o arquivo como uma variedade de caracteres, e o sistema operacional deve cuidar de todo o buffer de baixo nível para você. A solução mais simples e provavelmente mais rápida é uma vitória do meu livro. :)

Aqui é uma excelente referência que mostra que em condições extremas, fstreamS realmente são bastante lentos ... a menos:

  1. Você usa buffer (não posso enfatizar isso o suficiente)
  2. Você mesmo manipula o buffer (ou seja, se precisa de desempenho como OP na pergunta vinculada), que não é tão diferente de usar FILE*.

Você não deve otimizar prematuramente, no entanto. fstreams geralmente são melhores e, se você precisar otimizá -los na estrada, sempre poderá fazê -lo mais tarde com pouco custo. Para se preparar para o pior com antecedência, sugiro criar um proxy mínimo para fstream Agora, para que você possa otimizá -lo mais tarde, sem precisar tocar em qualquer outra coisa.

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