2010-11-26 16 views
5

Estoy creando una extensión de Firefox que permite el uso de Standard ML (SML) como un lenguaje de programación del lado del cliente en Firefox. La forma en que funciona es la siguiente:¿Cuáles son los límites de usar sockets para la comunicación entre procesos?

  1. La extensión inicia un proceso PolyML (compilador SML con un shell interactivo de nivel superior).
  2. Luego se establece una comunicación de socket entre la extensión y el proceso PolyML.
  3. El código SML se lee de la página web y se envía a través de sockets al proceso PolyML para su evaluación.
  4. Ese código puede utilizar una biblioteca que proporciono para trabajar con el DOM.

Aquí es cómo se implementa la biblioteca DOM:

  1. decir que alguien ejecuta una función SML DOM.getElementById
  2. Esta solicitud se reenvía a través de las basas de la extensión, donde la extensión ejecuta el código JavaScript función getElementById en la página y envía el resultado al proceso PolyML a través de los sockets.

Mi pregunta es, en teoría, ¿qué límites en términos de rendimiento debería esperar tener aquí, cuando se trata de la comunicación de socket?

he hecho un poco de perfiles muy aproximada y parece que el uso de esta interfaz entre la extensión y PolyML, I aproximadamente puedo enviar 2500 mensajes/segundo, de un tamaño medio de 70 bytes/mensaje.

Para poner esto en un contexto más amplio, supongamos que quiero dibujar algunas animaciones en el navegador utilizando el elemento Canvas. Si quiero alcanzar 20 fps, eso significa que necesito dibujar cada fotograma en 0.05 segundos, lo que significa que solo puedo enviar alrededor de 125 mensajes por fotograma. Esos mensajes corresponden a llamadas de funciones de JavaScript. Por ejemplo, el siguiente código dibuja una ruta y está realizando 9 llamadas a función de JavaScript, que corresponden a 9 mensajes en la comunicación de socket.

val _ = Canvas.beginPath context; 
val _ = Canvas.setFillStyle context fillColor; 
val _ = Canvas.setStrokeStyle context fillColor; 
val _ = Canvas.setLineWidth context size; 
val _ = Canvas.moveTo context posx posy; 
val _ = Canvas.lineTo context posx_new posy_new; 
val _ = Canvas.stroke context; 
val _ = Canvas.arc context posx_new posy_new (size/2.0) 0.0 6.28 true; 
val _ = Canvas.fill context; 

JavaScript, obviamente, tiene un rendimiento mucho mejor, me imagino que usted podría hacer miles (cientos) de los momentos de más funciones/DOM lienzo llamadas en aquellos 0,05 segundos, para la elaboración de un marco .

Entonces, supongo que mi pregunta es, ¿tiene alguna experiencia con el uso de la comunicación de socket para el intercambio de mensajes muy rápido. Me gustaría saber si 2500 pequeños mensajes/segundo (en este caso, que corresponden a 150 kbytes/segundo) parece correcto o podría estar haciendo algo muy mal.

Por ejemplo, una sospecha es que la implementación de socket en firefox (en particular usarlo a través de la interfaz de JavaScript https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket) no es muy buena para este tipo de interacción rápida. Por ejemplo, la lectura del socket se realiza a través de un mecanismo de ciclo de eventos. Es decir, confío en Firefox para notificarme sobre la disponibilidad de los mensajes de socket entrantes y, a veces, hay un retraso grande (por ejemplo, 250 ms) entre enviar el mensaje y recibirlo (aunque parece estar sucediendo solo cuando Firefox está ocupado haciendo otras cosas, y estoy más interesado en la ... teoría ...límites de la comunicación del zócalo)

¿Alguna idea, algún pensamiento, algún defecto que vea? ¿Cree que usar otros mecanismos de IPC sería mejor, p. tuberías, la implementación de mi comunicación desde el componente C++ XPCOM, en lugar de JavaScript, interfaz de función extranjera a C (que tienen JavaScript y PolyML)?

(El proyecto se encuentra en https://assembla.com/wiki/show/polymlext si alguien está interesado)

+0

¿Estás utilizando TCP? UDP? o tomas de corriente UNIX? Este último debería ser más rápido ya que el sistema operativo no tiene que preocuparse por los errores de red. – bew

+0

no estoy seguro, estaba usando https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket. ¿Sabes si son TCP, UNIX o configurables? – Karolis

+0

También me di cuenta de que el cuello de botella podría ser la codificación/decodificación JSON, aunque ya no recuerdo cuánto de eso se usó allí. – Karolis

Respuesta

1

TCP puede ser sintonizado para un mayor rendimiento o tiempo de respuesta más rápido. Para un mayor rendimiento, debe establecer el búfer de socket a un valor mayor. Para obtener un buen tiempo de respuesta con un fragmento de datos más pequeño, debe configurar la opción de socket TCP_NODELAY. TCP en bucle de retroceso si está afinado debe ser idéntico a cualquier mecanismo de IPC. El sistema operativo Windows más nuevo ofrece una optimización especial, como aumentar el tamaño de MTU, etc. en el adaptador de bucle invertido para hacerlo más rápido.

Cuestiones relacionadas