¿Qué hace a Ruby lento? [cerrado]


Ruby es lento en ciertas cosas. Pero, ¿qué partes son las más problemáticas?

¿Cuánto afecta el recolector de basura al rendimiento? Sé que he tenido momentos en los que ejecutar el recolector de basura solo tomó varios segundos, especialmente cuando se trabaja con bibliotecas OpenGL.

He usado bibliotecas de matemáticas matriciales con Ruby que eran particularmente lentas. ¿Hay algún problema con cómo ruby implementa matemáticas básicas?

¿ Hay alguna característica dinámica en Ruby que simplemente no puede ser ¿implementado eficientemente? Si es así, ¿cómo resuelven estos problemas otros lenguajes como Lua y Python?

¿Ha habido trabajos recientes que hayan mejorado significativamente el rendimiento?

Author: Robert S., 2009-06-18

9 answers

Ruby es lento. Pero, ¿qué partes son las más problemáticas?

Hace "búsqueda tardía" de métodos, para permitir flexibilidad. Esto lo ralentiza un poco. También tiene que recordar nombres de variables por contexto para permitir eval, por lo que sus frames y llamadas a métodos son más lentas. También carece de un buen compilador JIT actualmente, aunque MRI 1.9 tiene un compilador de bytecode (que es mejor), y jruby lo compila a bytecode java, que luego (puede) compilar a través del HotSpot JVM Compilador JIT, pero termina siendo aproximadamente la misma velocidad que la 1.9.

¿Cuánto afecta el rendimiento del recolector de basura? Sé que he tenido momentos en los que ejecutar el recolector de basura solo tomó varios segundos, especialmente cuando se trabaja con bibliotecas OpenGL.

De algunos de los gráficos en http://www.igvita.com/2009/06/13/profiling-ruby-with-googles-perftools / Yo diría que se necesita alrededor de 10% que es un poco can se puede disminuir ese golpe mediante el aumento de la malloc_limit en gc.c y recompilación.

He usado bibliotecas de matemáticas matriciales con Ruby que eran particularmente lentas. ¿Hay algún problema con cómo ruby implementa matemáticas básicas?

Ruby 1.8 "no implementó" matemáticas básicas implementó clases numéricas y llamarías a cosas como Fixnum#+ Fixnum#/ una vez por llamada which lo cual era lento. Ruby 1.9 engaña un poco insertando algunas de las operaciones matemáticas básicas.

¿Hay alguna característica dinámica en Ruby que simplemente no puede ser ¿implementado eficientemente? Si es así, ¿cómo resuelven estos problemas otros lenguajes como Lua y Python?

Cosas como eval son difíciles de implementar de manera eficiente, aunque se puede hacer mucho trabajo, estoy seguro. El truco para Ruby es que tiene que acomodarse para alguien en otro hilo cambiando la definición de una clase espontáneamente, por lo que tiene que ser muy conservador.

¿Ha habido trabajos recientes que hayan mejorado significativamente el rendimiento?

1.9 es como un aumento de velocidad 2x. También es más eficiente en el espacio. JRuby está constantemente tratando de mejorar la velocidad [y probablemente pasa menos tiempo en la GC que KRI]. Además de eso, no soy consciente de muchas cosas excepto pequeñas cosas de pasatiempos en las que he estado trabajando. Tenga en cuenta también que las cadenas 1.9 son a veces más lentas debido a la facilidad de codificación.

 69
Author: rogerdpack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-12 03:51:06

Ruby es muy bueno para entregar soluciones rápidamente. Menos para ofrecer soluciones rápidas. Depende del tipo de problema que trates de resolver. Me acuerdo de las discusiones en el antiguo foro CompuServe MSBASIC a principios de los 90: cuando se le preguntó cuál era más rápido para el desarrollo de Windows, VB o C, la respuesta habitual fue "VB, por unos 6 meses".

En su forma MRI 1.8, Ruby es - relativamente - lento para realizar algunos tipos de tareas computacionalmente intensivas. Casi cualquier interpretado el lenguaje sufre de esa manera en comparación con la mayoría de los lenguajes compilados convencionales.

Las razones son varias: algunas bastante fácilmente direccionables (la recolección de basura primitiva en 1.8, por ejemplo), algunas menos.

1.9 aborda algunos de los problemas, aunque probablemente pasará algún tiempo antes de que esté disponible de forma general. Algunas de las otras implementaciones que se dirigen a tiempos de ejecución preexistentes, JRuby, IronRuby, MagLev, por ejemplo, tienen el potencial de ser significativamente más rápido.

En cuanto al rendimiento matemático, no me sorprendería ver un rendimiento bastante lento: es parte del precio que se paga por la precisión arbitraria. Una vez más, elige tu problema. He resuelto más de 70 de los problemas del Proyecto Euler en Ruby con casi ninguna solución que requiera más de un minuto para ejecutarse. ¿Qué tan rápido lo necesitas para correr y qué tan pronto lo necesitas?

 11
Author: Mike Woodhouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-18 08:54:06

La parte más problemática es "todos".

Puntos de bonificación si ese "todo el mundo" no usó realmente el idioma, nunca.

En serio, 1.9 es mucho más rápido y ahora está a la par con python, y jruby es más rápido que jython.

Los recolectores de basura están en todas partes; por ejemplo, Java tiene uno, y es más rápido que C++ en el manejo de memoria dinámica. Ruby no se adapta bien para calcular números; pero pocos lenguajes lo son, así que si tienes partes computacionales intensivas en tu programa en cualquier lenguaje, es mejor reescribirlos en C (Java es rápido con las matemáticas debido a sus tipos primitivos, pero pagó caro por ellos, son claramente #1 en las partes más feas del lenguaje).

En cuanto a las características dinámicas: no son rápidas, pero el código sin ellas en lenguajes estáticos puede ser aún más lento; por ejemplo, java usaría una configuración XML en lugar de Ruby usando un DSL; y probablemente sería más LENTO ya que el análisis XML es costoso.

 9
Author: alamar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-18 08:40:39

Hmm - Trabajé en un proyecto hace unos años donde raspé el barril con Ruby performance, y no estoy seguro de que haya cambiado mucho desde entonces. Ahora mismo es caveat emptor-tienes que saber no hacer ciertas cosas, y francamente juegos / aplicaciones en tiempo real sería una de ellas (ya que mencionas OpenGL).

El culpable de matar el rendimiento interactivo es el recolector de basura-otros aquí mencionan que Java y otros entornos también tienen recolección de basura, pero Ruby tiene que detener el mundo para correr. Es decir, tiene que dejar de ejecutar su programa, escanear a través de cada registro y puntero de memoria desde cero, marcar la memoria que todavía está en uso, y liberar el resto. El proceso no se puede interrumpir mientras esto sucede, y como habrás notado, puede tomar cientos de milisegundos.

Su frecuencia y duración de ejecución es proporcional al número de objetos que cree y destruya, pero a menos que lo deshabilite por completo, no tiene control. Mi experiencia fue que había varias estrategias insatisfactorias para suavizar mi bucle de animación Ruby:

  • GC.desactivar / GC.habilite alrededor de bucles de animación críticos y tal vez un GC oportunista.empieza a forzarlo a irse cuando no pueda hacer ningún daño. (debido a que mi plataforma de destino en ese momento era una máquina Windows NT de 64 MB, esto causó que el sistema se quedara sin memoria ocasionalmente. Pero fundamentalmente es una mala idea, a menos que pueda pre-calcular la cantidad de memoria que podría necesitar antes haciendo esto, usted está arriesgando agotamiento de la memoria)
  • Reduzca el número de objetos que crea para que el GC tenga menos trabajo que hacer (reduce la frecuencia / duración de su ejecución)
  • Reescribe tu bucle de animación en C (¡un cop-out, pero con el que fui!)

En estos días, probablemente también vería si JRuby funcionaría como un tiempo de ejecución alternativo, ya que creo que se basa en el recolector de basura más sofisticado de Java.

El otro problema importante de rendimiento que he encontrado es básico E / S al intentar escribir un servidor TFTP en Ruby hace un tiempo (sí, elijo todos los mejores idiomas para mis proyectos críticos de rendimiento, esto fue solo un experimento). El bucle más simple y apretado para responder simplemente a un paquete UDP con otro, contaneando la siguiente pieza de un archivo, debe haber sido aproximadamente 20 veces más lento que la versión estándar de C. Sospecho que podría haber habido algunas mejoras para hacer allí basado en el uso de E / s de bajo nivel (sysread, etc.) pero la lentitud podría estar en el hecho no hay un tipo de datos de bytes de bajo nivel-cada pequeña lectura se copia en una cadena. Sin embargo, esto es solo especulación, no llevé este proyecto mucho más lejos, pero me advirtió que no confiara en E/S rápidas.

El aumento reciente de velocidad principal que ha continuado, aunque no estoy completamente actualizado aquí, es que la implementación de la máquina virtual se rehizo para la versión 1.9, lo que resulta en una ejecución de código más rápida. Sin embargo No creo que el GC haya cambiado, y estoy bastante seguro de que no hay nada nuevo en el frente de E / S. Pero no estoy completamente al día con Ruby, así que alguien más podría querer contribuir aquí.

 8
Author: Matthew Bloch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-21 01:05:47

Steve Dekorte: "Escribir una calculadora de Mandelbrot en un lenguaje de alto nivel es como intentar ejecutar la Indy 500 en un autobús."

Http://www.dekorte.com/blog/blog.cgi?do=item&id=4047

Recomiendo aprender varias herramientas con el fin de utilizar la herramienta adecuada para el trabajo. Hacer transformaciones de matriz se podría hacer de manera eficiente utilizando API de alto nivel que envuelve alrededor de bucles apretados con cálculos aritméticos intensivos. Consulte RubyInline gem para ver un ejemplo de incrustación de C o C++ código en Ruby script.

También hay lenguaje Io que es mucho más lento que Ruby, pero renderiza eficientemente películas en Pixar y supera a raw C en aritmética vectorial mediante el uso de aceleración SIMD.

 4
Author: Oleg Andreev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-18 08:46:59

Asumo que estás preguntando, "qué técnicas particulares en Ruby tienden a ser lentas."

Uno es la instanciación de objetos. Si usted está haciendo grandes cantidades de él, usted quiere mirar en maneras (razonables) de reducir eso, por ejemplo usando el patrón flyweight, incluso si el uso de memoria no es un problema. En una biblioteca donde la reelaboré para no crear muchos objetos muy similares una y otra vez, duplicé la velocidad general de la biblioteca.

 4
Author: Curt J. Sampson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-21 01:24:33

Ruby 1.9.1 es aproximadamente el doble de rápido que PHP, y un poco más rápido que Perl, según algunos puntos de referencia.

(Actualización: Mi fuente es este (captura de pantalla). Aunque no se cual es su fuente.)

Ruby no es lento. El antiguo 1.8 lo es, pero el Ruby actual no.

 3
Author: August Lilleaas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-22 06:59:43

Ruby es lento porque fue diseñado para optimizar la experiencia de los programadores, no el tiempo de ejecución del programa. La lentitud es solo un síntoma de esa decisión de diseño. Si prefieres el rendimiento al placer, probablemente deberías usar un idioma diferente. Ruby no es para todo.

 2
Author: Joe Flynn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-25 15:53:55

IMO, los lenguajes dinámicos son todos lentos en general. Hacen algo en tiempo de ejecución que los lenguajes estáticos hacen en tiempo de compilación.

Comprobación de sintaxis, Interpretación y comprobación de tipo similar, conversión. esto es inevitable, por lo tanto ruby es más lento que c/c++ / java, corrígeme si me equivoco.

 1
Author: c2h2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-28 15:01:13