He leído en muchos lugares (diablos, incluso he escrito yo mismo) que la recolección de basura podría (en teoría) ser más rápida que la gestión manual de la memoria.
Sin embargo, mostrar es mucho más difícil de encontrar que contar.
Nunca he visto ningún fragmento de código que demuestre este efecto en acción.
¿Alguien tiene (o sabe dónde puedo encontrar) código que demuestre esta ventaja de rendimiento?
memory
garbage-collection
Mehrdad
fuente
fuente
Respuestas:
Consulte http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx y siga todos los enlaces para ver a Rico Mariani vs Raymond Chen (ambos programadores muy competentes en Microsoft) duelo. . Raymond mejoraría el no administrado, Rico respondería optimizando lo mismo en los administrados.
Con un esfuerzo de optimización esencialmente cero, las versiones administradas comenzaron muchas veces más rápido que el manual. Finalmente, el manual superó al administrado, pero solo optimizando a un nivel al que la mayoría de los programadores no querrían ir. En todas las versiones, el uso de memoria del manual fue significativamente mejor que el administrado.
fuente
swap
) no es tan difícil, y probablemente lo lleve a usted con bastante facilidad en cuanto al rendimiento ...La regla general es que no hay almuerzos gratis.
GC elimina el dolor de cabeza de la gestión manual de la memoria y reduce la probabilidad de cometer errores. Hay algunas situaciones en las que una estrategia de GC particular es la solución óptima para el problema, en cuyo caso no pagará ninguna penalización por usarlo. Pero hay otros donde otras soluciones serán más rápidas. Dado que siempre puedes simular abstracciones más altas desde un nivel más bajo, pero no al revés, puedes demostrar efectivamente que no hay forma de que las abstracciones más altas puedan ser más rápidas que las más bajas en el caso general.
GC es un caso especial de gestión manual de memoria
Puede ser mucho trabajo o más propenso a errores para obtener un mejor rendimiento de forma manual, pero esa es una historia diferente.
fuente
Es fácil construir una situación artificial en la que el GC sea infinitamente más eficiente que los métodos manuales: simplemente organice que solo haya una "raíz" para el recolector de basura, y que todo sea basura, de modo que el paso del GC se complete al instante.
Si lo piensa, ese es el modelo utilizado cuando se recolecta basura la memoria asignada a un proceso. El proceso muere, toda su memoria es basura, hemos terminado. Incluso en términos prácticos, un proceso que se inicia, se ejecuta y muere sin dejar rastro podría ser más eficiente que uno que se inicia y se ejecuta para siempre.
Para programas prácticos, escritos en idiomas con recolección de basura, la ventaja de la recolección de basura no es la velocidad sino la corrección y la simplicidad.
fuente
abort()
a C ++ antes de que el programa salga. Es una comparación sin sentido; Ni siquiera estás recogiendo basura, solo estás dejando que la memoria se escape. No puedes decir que la recolección de basura es más rápida (o más lenta) si no estás recolectando basura para empezar ...Debe considerarse que GC no es solo una estrategia de administración de memoria; También exige todo el diseño del lenguaje y el entorno de tiempo de ejecución, que imponen costos (y beneficios). Por ejemplo, un lenguaje que admita GC debe compilarse en una forma en la que los punteros no se puedan ocultar del recolector de basura y, en general, donde no se puedan construir, excepto por primitivas del sistema cuidadosamente administradas. Otra consideración es la dificultad de mantener las garantías de tiempo de respuesta, ya que GC impone algunos pasos que se deben permitir que se ejecuten hasta su finalización.
En consecuencia, si tiene un idioma que es basura recolectada y compara la velocidad con la memoria administrada manualmente en el mismo sistema, aún tiene que pagar los gastos generales para admitir la recolección de basura, incluso si no lo está usando.
fuente
Más rápido es dudoso. Sin embargo, puede ser ultrarrápido, imperceptible o más rápido si es compatible con hardware. Hubo diseños como ese para máquinas LISP hace mucho tiempo. Uno incorporó el GC en el subsistema de memoria del hardware como tal que la CPU principal no sabía que estaba allí. Al igual que muchos diseños posteriores, el GC se ejecutó simultáneamente con el procesador principal con poca o ninguna necesidad de pausas. Un diseño más moderno son las máquinas Azul Systems Vega 3 que ejecutan código Java mucho más rápido que las JVM que utilizan procesadores especialmente diseñados y un GC sin pausa. Busca en Google si quieres saber qué tan rápido puede ser GC (o Java).
fuente
He trabajado bastante en esto y he descrito algo de esto aquí . Comparé el GC de Boehm en C ++, asignando usando
malloc
pero no liberando, asignando y liberando usandofree
y un GC de región de marca personalizado escrito en C ++ todos contra el GC de stock de OCaml que ejecuta un solucionador de n-reinas basado en listas. El GC de OCaml fue más rápido en todos los casos. Los programas C ++ y OCaml se escribieron deliberadamente para realizar las mismas asignaciones en el mismo orden.Por supuesto, puede reescribir los programas para resolver el problema utilizando solo enteros de 64 bits y sin asignaciones. Aunque más rápido eso derrotaría el objetivo del ejercicio (que era predecir el rendimiento de un nuevo algoritmo GC en el que estaba trabajando usando un prototipo construido en C ++).
He pasado muchos años en la industria portando código C ++ real a lenguajes administrados. En casi todos los casos, observé mejoras sustanciales en el rendimiento, muchas de las cuales probablemente se debieron a la gestión manual de la memoria del GC. La limitación práctica no es lo que se puede lograr en un microbenchmark, sino lo que se puede lograr antes de una fecha límite y los lenguajes basados en GC ofrecen mejoras de productividad tan enormes que nunca miré hacia atrás. Todavía uso C y C ++ en dispositivos integrados (microcontroladores) pero incluso eso está cambiando ahora.
fuente
List.filter
como lo hace C ++. Pero sí, ciertamente tiene toda la razón en que algunas operaciones de RC pueden eludirse. Sin embargo, el mayor problema que veo en la naturaleza es que las personas no tienen tiempo para realizar tales optimizaciones a mano en grandes bases de códigos industriales.shared_ptr
solo para corregir errores de concurrencia. El código es mucho más lento pero, bueno, ahora funciona.Tal ejemplo necesariamente tiene un mal esquema de asignación de memoria manual.
Asumir el mejor recolector de basura
GC
. Internamente tiene métodos para asignar memoria, determinar qué memoria se puede liberar y métodos para finalmente liberarla. Juntos, estos toman menos tiempo que todosGC
; se pasa algún tiempo en los otros métodos deGC
.Ahora considere un asignador manual que usa el mismo mecanismo de asignación que
GC
, y cuyafree()
llamada simplemente deja de lado la memoria que se liberará por el mismo método queGC
. No tiene una fase de exploración, ni tiene ninguno de los otros métodos. Necesariamente lleva menos tiempo.fuente
free
también puede recolectar lotes. (Y, por supuesto, eliminar todos los elementos que cumplen un criterio sigue siendo O (N), aunque solo sea por el recorrido de la lista en sí)free
podría funcionar en un modo de recopilación por lotes si cada elemento de memoria tuviera un indicador asociado, aunque el GC todavía puede salir adelante en algunas situaciones. Si uno tiene M referencias que identifican L elementos distintos de un conjunto de N cosas, el tiempo para eliminar cada referencia a la que no existe ninguna referencia y consolidar el resto es O (M) en lugar de O (N). Si uno tiene M espacio adicional disponible, la constante de escala puede ser bastante pequeña. Además, la compactación en un sistema GC sin escaneo requiere ...