Pregunta

¿Cuál es la diferencia, en términos de rendimiento, entre leer desde un socket 1 byte por vez y leer en trozos grandes?

Tengo una aplicación C++ que necesita extraer páginas de un servidor web y analizar la página recibida línea por línea.Actualmente, estoy leyendo 1 byte a la vez hasta que encuentro un CRLF o se alcanza el máximo de 1024 bytes.

Si lee en fragmentos grandes (p. ej.1024 bytes a la vez) es mucho mejor en cuanto a rendimiento, cualquier idea sobre cómo lograr el mismo comportamiento que tengo actualmente (es decir,¿Poder almacenar y procesar 1 línea html a la vez, hasta el CRLF sin consumir los bytes siguientes todavía)?

EDITAR:

No puedo permitirme buffers demasiado grandes.Tengo un presupuesto de código muy ajustado ya que la aplicación se utiliza en un dispositivo integrado.Prefiero mantener solo un búfer de tamaño fijo, preferiblemente mantener una línea html a la vez.Esto facilita mi análisis y otros procesos, ya que cada vez que intento acceder al búfer para analizar, puedo asumir que estoy procesando una línea html completa.

Gracias.

¿Fue útil?

Solución

Si está leyendo directamente desde el socket, y no desde una representación intermedia de nivel superior que pueda almacenarse en un buffer, entonces, sin ninguna duda, es mejor leer completamente los 1024 bytes, colocarlos en la RAM en un buffer y luego analizar los datos de la RAM.

¿Por qué?La lectura en un socket es una llamada al sistema y provoca un cambio de contexto en cada lectura, lo cual es costoso.Lea más sobre esto: Biblioteca técnica de IBM:Mejorar el rendimiento del socket

Otros consejos

No puedo hacer comentarios sobre C ++, pero desde otras plataformas - Sí, esto puede hacer que un grande diferencia; particularmente en la cantidad de interruptores el código tiene que hacer, y el número de veces que tiene que preocuparse acerca de la naturaleza asíncrona de corrientes, etc.

Pero la verdadera prueba es, por supuesto, para el perfil it. ¿Por qué no escribir una aplicación básica que produce en serie a través de un archivo arbitrario utilizando los dos sistemas, y probarlo para algunos archivos típicos ... el efecto es sorprendente por lo general, si el código está obligado IO. Si los archivos son pequeños y la mayor parte de su tiempo de ejecución de aplicaciones se gasta procesamiento los datos una vez que está en la memoria, no es probable que note ninguna diferencia.

Lo primero y más simple:

cin.getline(buffer,1024);

En segundo lugar, por lo general todo IO es amortiguada por lo que no tiene que preocuparse demasiado

En tercer lugar, proceso CGI se inicia por lo general cuesta mucho más que el procesamiento de entrada (a menos que sea enorme archivo) ... Así que es posible que simplemente no pensar en ello.

Buen día,

Uno de los grandes éxitos de rendimiento Al hacerlo de un byte a la vez es que su contexto va de vez usuario a la hora del sistema y otra vez. Y más. No es eficiente en absoluto.

Agarrando un gran paquete, normalmente hasta un tamaño de MTU, es mensurable más eficiente.

¿Por qué no explorar el contenido en un vector y iterar sobre que mirar hacia fuera para n de \ para separar su entrada en las líneas de entrada web?

HTH

aplausos,

Usted no está leyendo un byte a la vez de una toma, que está leyendo un byte a la atime del sistema de E / S en C / C ++ I, que si está utilizando CGI tendrá alreadety amortiguada por toda la entrada de la enchufe. El punto de búfer de E / S es hacer que los datos estén disponibles para el programador de una manera que es conveniente para ellos para procesar, por lo que si desea procesar un byte a la vez, seguir adelante.

Editar en la reflexión, no es claro por su pregunta si está implementando CGI o simplemente usarlo. Se podría aclarar esto mediante la publicación de un fragmento de código que indica cómo se lee actualmente leído que solo byte.

Si está leyendo la toma directa, entonces simplemente debe leer toda la respuesta al entrar en una memoria intermedia y luego procesarlo. Esto tiene numerosas ventajas, como el rendimiento y la facilidad de codificación.

Si está linitted a un pequeño búfer, a continuación, utilizar algoritmos tampón clásicos como:

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

Puede abrir el archivo de socket descritpor con la función fdopen (). A continuación, han tamponada IO para que pueda llamar fgets () o similares en ese descriptor.

No hay ninguna diferencia en el nivel de sistema operativo, los datos se almacenan todos modos. Su aplicación, sin embargo, debe ejecutar más código para "leer" bytes uno a la vez.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top