Pergunta

Eu estou escrevendo um programa onde o desempenho é muito importante, mas não crítico. Atualmente estou lendo no texto de uma linha FILE* por linha e eu uso fgets para obter cada linha. Depois de usar algumas ferramentas de desempenho, eu descobri que 20% a 30% do tempo meu aplicativo está sendo executado, é fgets dentro.

Existem maneiras mais rápidas de obter uma linha de texto? A minha aplicação é single-threaded com nenhuma intenção de usar vários segmentos. Entrada poderia ser de stdin ou de um arquivo. Agradecemos antecipadamente.

Foi útil?

Solução

Você não diz qual plataforma você está, mas se for UNIX-like, então você pode querer tentar a chamada de sistema read (), que não executa a camada extra de tamponamento que fgets () et al Faz. Isso pode acelerar as coisas um pouco, por outro lado, pode bem as coisas lentas para baixo -. A única maneira de descobrir é tentar e ver

Outras dicas

  1. Use fgets_unlocked (), mas leia atentamente o que ele faz primeira

  2. Obter os dados com fgetc () ou fgetc_unlocked () em vez de fgets (). Com fgets (), os dados são copiados para a memória duas vezes, primeiro pela biblioteca C de tempo de execução de um arquivo para um buffer interno (fluxo de I / O é tamponado), então a partir desse buffer interno para uma matriz em seu programa

Leia o arquivo inteiro de uma só vez em um buffer.

Processe as linhas de que o tampão.

Essa é a solução mais rápida possível.

Você pode tentar minimizar a quantidade de tempo que você gasta lendo a partir do disco por leitura de grandes quantidades de dados na RAM, em seguida, trabalhando nisso. Leitura do disco é baixa, para minimizar a quantidade de tempo que você gasta fazendo isso através da leitura (idealmente) o arquivo inteiro uma vez, então a trabalhar nele.

Sorta como o cache de maneira CPU minimiza o tempo da CPU na verdade remonta a RAM, você poderia usar RAM para minimizar o número de vezes que você realmente ir para o disco.

Dependendo do seu ambiente, usando setvbuf () para aumentar o tamanho do buffer interno usado por fluxos de arquivo pode ou não melhorar o desempenho.

Esta é a sintaxe -

setvbuf (InputFile, NULL, _IOFBF, BUFFER_SIZE);

Onde InputFile é um FILE * para um arquivo apenas abertos usando fopen () e BUFFER_SIZE é o tamanho do buffer (que é alocada por esta chamada para você).

Você pode experimentar vários tamanhos de buffer para ver se algum tem influência positiva. Note-se que este é totalmente opcional, e seu tempo de execução pode fazer absolutamente nada com esta chamada.

Se os dados é proveniente de disco, você pode ser obrigado IO.

Se for esse o caso, obter um disco mais rápido (mas primeiro cheque que você está recebendo o máximo proveito do seu já existente ... algumas distribuições Linux não acesso otimizar disco fora da caixa (hdparm)), encenar os dados na memória (digamos, copiando-o para um disco RAM) antes do tempo, ou estar preparado para esperar.


Se você não IO ligados são, você pode estar perdendo muito tempo copiando. Você poderia beneficiar os chamados métodos de cópia zero. Algo como memória mapear o arquivo e só acessá-lo através de ponteiros.

Isso é um pouco além da minha experiência, então você deve fazer algumas leituras ou esperar por uma ajuda mais experiente.

BTW-- Você pode estar se metendo mais trabalho do que o problema vale a pena; talvez uma máquina mais rápida iria resolver todos os seus problemas ...

NB-- Não é claro que você pode memória mapear a entrada padrão ou ...

Olhe em fread (). Lê-se muito mais rápido para mim, especialmente se tampão para fread está definido para 65536. Contras: você tem que fazer um monte de trabalho e, essencialmente, escrever sua própria função getline converter de leitura binário para texto. Confira: arquivo I / O

Se os suportes OS-lo, você pode tentar a leitura de arquivos assíncrona, ou seja, o arquivo é lido na memória enquanto a CPU está ocupado fazendo outra coisa. Assim, o código é algo como:

start asynchronous read
loop:
  wait for asynchronous read to complete
  if end of file goto exit
  start asynchronous read
  do stuff with data read from file
  goto loop
exit:

Se você tiver mais de uma CPU, em seguida, uma CPU lê o arquivo e analisa os dados em linhas, a outra CPU leva cada linha e processos de TI.

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