jruby jrubyonrails

JRuby Performance



jrubyonrails (3)

¡Actualice a jruby 1.6.8 o jruby 1.7.x con JAVA 7!

Excelente actuación.

Tuvimos el mismo problema y es tremendamente rápido ahora (con solo cambiar las versiones).

Tengo una aplicación Rails 3.2.2 que intento ejecutar con JRuby 1.6.7 (modo 1.9.2).

Tengo una aplicación de muestra que se ejecuta en MRI ruby ​​1.9.3 y una solicitud típica está regresando en ~ 40ms: Completó 200 OK en 36ms (Vistas: 27.5ms | ActiveRecord: 8.2ms)

Según JRuby, usar la misma solicitud es entre 3 y 20 veces más lento según la página. Para la misma operación anterior, se necesitan ~ 180ms: se completaron 200 OK en 180ms (Vistas: 153.0ms | ActiveRecord: 24.0ms)

¿Es esta una diferencia de rendimiento normal? He leído que JRuby es aproximadamente igual en velocidad con MRI. Los resultados se mantienen en mi Mac y en un servidor de Windows (donde, lamentablemente, tendrá que ejecutarse). Empaquetarlo con Warbler ejecutándose bajo Tomcat es igual de lento.

Los tiempos anteriores son de una aplicación de rieles básica creada para probar el JRuby. En la aplicación más compleja, los tiempos están aún más separados. En esa aplicación hay más código ruby ​​ejecutándose en algunas páginas. Parece que cuanto más dependa Ruby de la página, mayor será la diferencia de rendimiento que estoy observando. No he hecho ningún ajuste de JRuby, ya que no sé muy bien por dónde empezar.

Así que mis preguntas son: ¿es esto normal? ¿Qué puedo hacer para sintonizar JRuby?


Estoy viendo el mismo comportamiento, pero tenga en cuenta que JRuby necesita mucho más tiempo para calentarse. De hecho, soy un poco optimista de que JRuby finalmente se pondrá al día.

Es posible hacer que este ''calentamiento'' sea más rápido configurando algunas opciones. El compilador Ruby -> Java Bytecode puede enseñarse a JIT a compilar todos los métodos en la primera invocación configurando las siguientes env var:

export JRUBY_OPTS="-J-Djruby.jit.threshold=1 -J-Djruby.jit.max=16384"

Para mí, después de actualizar una página de Rails varias veces, sigue siendo 2-3 veces más lento que el MRI Ruby, pero al menos 3 veces más rápido que antes.

También tenga en cuenta que el tiempo de ejecución de Java es JIT que compila el código de bytes de Java al código de máquina de una manera similar, pero este JIT no se activará hasta que se invoque un método 10.000x cuando se usa el tiempo de ejecución del servidor. Esto también se puede configurar .

export JRUBY_OPTS="-J-Djruby.jit.threshold=10 -J-Djruby.jit.max=16384 -J-XX:CompileThreshold=10" -J-XX:ReservedCodeCacheSize=128M"

Con estas opciones, JRuby on Rails ofrece el mismo o mejor rendimiento que MRI.

Tenga en cuenta que estas opciones son solo para evaluaciones comparativas impacientes. En realidad, casi siempre es una mala idea ejecutar la compilación JIT de forma agresiva; Usted está perdiendo tiempo y memoria valiosos en la compilación JIT de código que puede ejecutarse solo unas pocas veces. Sin embargo, muestra cómo el rendimiento eventual de JRuby puede ser mejor de lo esperado según las ejecuciones iniciales.

Déjame saber si esto funciona para ti.


Is this a normal performance difference? I have read that JRuby is roughly equal on speed with MRI.

No, eso no es normal. Una vez que la JVM se ha calentado, las solicitudes de Rails bajo JRuby suelen tener un rendimiento significativamente mayor que bajo MRI, tanto en términos de velocidad de ejecución sin formato como de recolección de basura.

Parece que su aplicación está mal configurada. Lo primero que debe verificar es la configuración de Rails en sí. Asegúrese de que Rails no esté en modo de desarrollo, y que config.threadsafe! está habilitado en su entorno de producción. El modo Threadsafe dará como resultado que solo haya una copia compartida de Rails cargados en la memoria cuando su aplicación se esté ejecutando.

También verifique que la configuración de su base de datos aproveche la agrupación de conexiones, por ejemplo, pool: 20 en database.yml .

Finalmente, verifique la configuración de su JVM y JRuby, ambas son altamente ajustables. Debe asegurarse de que haya suficiente memoria asignada a la JVM al inicio, y luego suficiente memoria para que la aplicación funcione sin problemas; de lo contrario, la JVM se verá obligada constantemente a recolectar basura de forma prematura y frecuente, lo que degradará significativamente el rendimiento.

Por ejemplo, algunas de las configuraciones para un VPS modestamente especificadas podrían ser algo como:

-Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k

... pero no copie estos ajustes a ciegas! Tendrá que experimentar y averiguar qué es bueno para usted con respecto a los recursos de memoria disponibles en su servidor.

Dicho esto, si bien JRuby probablemente consumirá menos memoria que la suma total de múltiples procesos de Rails en MRI, definitivamente deberá asignar un poco más por adelantado para un solo proceso de JVM. Sé generoso con JRuby, y JRuby te recompensará por tu amabilidad :-)

Puede leer más sobre la optimización de JRuby y la JVM aquí: https://github.com/jruby/jruby/wiki/PerformanceTuning

Actualizar

No es necesario configurar config.threadsafe! en Rails 4.0 y superior; es seguro para subprocesos por defecto.