Pergunta

Como eu loop através de linhas no arquivo A, estou analisando a linha e colocar cada corda (char*) em um char**.

No final de uma linha, eu, em seguida, executar um procedimento que consiste em abrir o arquivo B, utilizando fgets, fseek e fgetc a personagens de agarrar a partir desse ficheiro. Eu arquivo em seguida, feche B.

repito reabertura e religamento arquivo B para cada linha.

O que eu gostaria de saber é:

  1. Existe um acerto de desempenho significativa de usar malloc e free, de tal forma que eu deveria usar algo estático como myArray[NUM_STRINGS][MAX_STRING_WIDTH] em vez de um char** myArray dinâmico?

  2. Existe significativa sobrecarga de desempenho de abertura e fechamento de arquivos B (Conceitualmente, muitos milhares de vezes)? Se meu arquivo A é ordenada, há uma maneira para eu usar fseek para mover "para trás" em arquivo B, para repor onde eu estava anteriormente localizado no arquivo B?

EDIT Revela-se que uma abordagem dupla reduzido grandemente o tempo de execução:

  1. Meu arquivo B é realmente uma das vinte e quatro arquivos. Em vez de abrir o mesmo arquivo B1 mil vezes, e em seguida, B2 mil vezes, etc. eu abrir arquivo B1 uma vez, fechá-lo, B2 uma vez, fechá-lo, etc. Isso reduz muitos milhares de operações fopen e fclose para cerca de 24.

  2. Eu costumava rewind() para repor o ponteiro de arquivo.

Isto proporcionou uma melhoria da velocidade de aproximadamente 60 vezes, o que é mais do que suficiente. Obrigado por me apontando para rewind().

Foi útil?

Solução

Se a sua matriz dinâmica cresce no tempo, há um custo cópia em algumas reallocs. Se você usa a heurística "sempre double", este é amortizado O (n), por isso não é horrível. Se você sabe a frente tamanho de tempo, uma matriz pilha alocada será ainda mais rápido.

Para a segunda pergunta ler sobre rewind. Ele tem que ser mais rápido do que abrir e fechar o tempo todo, e permite-lhe fazer menos gestão de recursos.

Outras dicas

O que eu gostaria de saber é:

  • faz o seu trabalho de código corretamente?
  • é que correr rápido o suficiente para o seu propósito?

Se a resposta de ambos estes é "sim", não mudam nada.

Abertura e fechamento tem uma variável sobrecarga dependendo se outros programas estão competitng para esse recurso.

medir o tamanho do arquivo primeiro e, em seguida, usar isso para calcular o tamanho da matriz com antecedência para fazer uma alocação grande heap.

Você não receberá um array multi-dimensional direita fora, mas um pouco de aritmética de ponteiro e você está lá.

Você não pode armazenar em cache informações de posição em outro arquivo e, em seguida, em vez de abrir e fechar, utilize anterior buscar índices como um deslocamento? Depende da lógica exata realmente.

  1. Se os arquivos são grandes, o disco I / O será muito mais caro do que o gerenciamento de memória. Preocupar-se com malloc / desempenho sem antes profiling indica que é um gargalo é otimização prematura.

  2. É possível que a sobrecarga de frequentes / fechar aberto é significativo em seu programa, mas novamente o / s real é provável que seja mais caro, a menos que os arquivos são pequenos, no caso da perda de buffers que entre perto e pode abrir potencialmente causar extra de disco I / O. E sim, você pode usar ftell () para obter a posição atual em um arquivo, em seguida, fseek com SEEK_SET para chegar a isso.

Há sempre um acerto de desempenho com o uso de memória dinâmica. Utilizando um tampão de estática vai proporcionar um aumento de velocidade.

Há também vai ser um acerto de desempenho com reabrir um arquivo. Você pode usar fseek (pos, SEEK_SET) para definir o ponteiro de arquivo para qualquer posição no arquivo ou fseek (offset, SEEK_CUR) para fazer um movimento relativo.

significativo impacto na performance é relativa, e você terá que determinar o que isso significa para si mesmo.

  1. Eu acho que é melhor para alocar o espaço real que você precisa, eo sobrecarga provavelmente não será significativo. Isso evita tanto perdendo espaço e pilha estouros

  2. Sim. Embora o IO é armazenada em cache, você está fazendo syscalls desnecessários (aberto e fechado). Use fseek com provavelmente SEEK_CUR ou SEEK_SET.

Em ambos os casos, há alguns hit desempenho, mas o significado vai depender do tamanho dos arquivos eo contexto seu programa é executado em.

  1. Se você realmente sabe o número máximo de strings e largura máxima, isso vai ser muito mais rápido (mas você pode perder uma grande quantidade de memória se você usar menos do que o "max"). O meio termo é fazer o que um monte de implementações de matriz dinâmica em C ++ fazer: sempre que você tem que myArray realloc, alloc duas vezes mais espaço que você precisa, e só realloc novamente uma vez que você ficar sem espaço. Isto tem O (n log) custo de desempenho.

  2. Isso pode ser um grande sucesso desempenho. Eu recomendo fortemente usando fseek, embora os detalhes vai depender do seu algoritmo.

muitas vezes eu achar o desempenho sobrecarga para ser superado pelo gerenciamento de memória direta que vem com malloc e esses manipuladores de baixo nível C na memória. A menos que essas áreas de memória estão indo para permanecer estático e intocado por uma quantidade de tempo que está em maior tempo amortizado de tocar essa memória, pode ser mais benéfico para ficar com a matriz estática. No final, cabe a você.

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