Pergunta

Qual é a diferença - em termos de performance -? Entre a leitura de um soquete 1 byte de cada vez vs lendo em grande parte

Eu tenho um aplicativo C ++ que as necessidades para puxar páginas de um servidor web e analisar a linha de página recebida por linha. Atualmente, estou lendo um byte de cada vez até eu encontrar um CRLF ou o máximo de 1024 bytes é atingido.

Se a leitura em grande parte (por exemplo, 1024 bytes de cada vez) é muito melhor em termos de performance, qualquer ideia sobre como conseguir o mesmo comportamento que eu tenho atualmente (isto é, ser capaz de armazenar e processar 1 linha de html em um momento -? até o CRLF sem consumir os bytes subsequentes até o momento)

EDIT:

Eu não posso pagar muito grandes buffers. Eu estou em um orçamento muito apertado código como o aplicativo é usado em um dispositivo embutido. I preferem manter apenas um tampão de tamanho fixo, de preferência para segurar uma linha html de cada vez. Isso faz com que a minha análise e outro processamento fácil como eu sou, por qualquer hora eu tento acessar a reserva para analisar, eu posso assumir que eu estou processando uma linha html completa.

Graças.

Foi útil?

Solução

Se você está lendo diretamente da tomada, e não a partir de uma representação de alto nível intermediário que pode ser tamponado, em seguida, sem qualquer dúvida possível, é apenas melhor para ler completamente os 1024 bytes, colocá-los na RAM em um buffer e, em seguida, analisar os dados da RAM.

Por quê? Leitura em um soquete é uma chamada de sistema, e isso provoca uma mudança de contexto em cada leitura, o que é caro. Leia mais sobre ele: IBM tecnologia Lib: performances de soquete impulso

Outras dicas

Não consigo comentário sobre C ++, mas a partir de outras plataformas - sim, isso pode fazer uma grande diferença; particularmente na quantidade de interruptores as necessidades de código para fazer, bem como o número de vezes que ele precisa se preocupar com a natureza assíncrona de fluxos etc.

Mas o verdadeiro teste é, naturalmente, para o perfil dele. Por que não escrever um aplicativo básico que bidões através de um arquivo arbitrário usando ambas as abordagens, e testá-lo para alguns arquivos típicos ... o efeito é geralmente assustando, se o código é IO bound. Se os arquivos são pequenos e maior parte do seu tempo de execução aplicativo é gasto processamento os dados, uma vez que está na memória, você não são susceptíveis de notar qualquer diferença.

Em primeiro lugar e mais simples:

cin.getline(buffer,1024);

Em segundo lugar, geralmente tudo IO é tamponado para que você não precisa se preocupar muito

Em terceiro lugar, início do processo CGI normalmente custa muito mais do que o processamento de entrada (a menos que ele é enorme arquivo) ... Então você pode simplesmente não pensar sobre isso.

G'day,

Um dos grandes sucessos de desempenho, fazendo-o um byte de cada vez é que o contexto está indo de tempo do usuário em tempo de sistema mais e mais. E acabou. Não é eficiente em tudo.

Pegando um pedaço grande, tipicamente até um tamanho MTU, é mensurável mais eficiente.

Por que não verificar o conteúdo em um vetor e iterar que olhar para fora para \ n é para separar o seu contributo para linhas de entrada web?

HTH

aplausos,

Você não está lendo um byte de cada vez de uma tomada, você está lendo um byte de cada atime do sistema de C / C ++ I / O, que se você estiver usando CGI terá alreadety tamponada toda a entrada do socket. O ponto inteiro de tampão I / O é disponibilizar os dados para o programador de uma forma que é conveniente para eles para processar, por isso, se você deseja processar um byte de cada vez, vá em frente.

Editar: Na reflexão, não é claro da sua pergunta se você estiver implementando CGI ou apenas usá-lo. Você poderia esclarecer isso por postar um trecho de código que indica como você atualmente ler li que único byte.

Se você está lendo o soquete diretamente, então você deve simplesmente ler a resposta inteira ao entrar em um buffer e, em seguida, processá-lo. Isto tem inúmeras vantagens, incluindo desempenho e facilidade de codificação.

Se você está linitted a um pequeno buffer, em seguida, usar algoritmos tamponamento clássicos como:

getbyte:
   if buffer is empty
      fill buffer
      set buffer pointer to start of buffer
   end
   get byte at buffer pointer
   increment pointer

Você pode abrir o descritpor arquivo de soquete com a função fdopen (). Então você tem tamponada IO para que você possa chamar fgets () ou semelhantes em que descritor.

Não há diferença no nível do sistema operacional, os dados são armazenados de qualquer maneira. Sua aplicação, no entanto, deve executar mais de código de "ler" bytes um de cada vez.

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