Porque hay una gran diferencia entre optimizar el rendimiento y desactivar por completo una seguridad
Al reducir la cantidad de GC, su marco es más receptivo y puede ejecutarse (presumiblemente) más rápido. Ahora, optimizar para el recolector de basura no significa que nunca hagan una recolección de basura. Simplemente significa que lo hacen con menos frecuencia, y cuando lo hacen, corre muy rápido. Ese tipo de optimización incluye:
- Minimizando el número de objetos que se mueven a un espacio de sobreviviente (es decir, que sobrevivió al menos a una recolección de basura) mediante el uso de pequeños objetos desechables. Los objetos que se movieron al espacio de sobrevivientes son más difíciles de recolectar y una recolección de basura aquí en algún momento implica congelar toda la JVM.
- Para empezar, no asigne demasiados objetos. Esto puede ser contraproducente si no tiene cuidado, ya que los objetos de la generación joven son muy baratos de asignar y recolectar.
- Asegúrese de que el objeto nuevo apunte al antiguo (y no al revés) para que el objeto joven sea fácil de recolectar, ya que no hay referencia a ellos que haga que se mantengan
Cuando desconecta el rendimiento, generalmente ajusta un "punto caliente" muy específico mientras ignora el código que no se ejecuta con frecuencia. Si hace eso en Java, puede dejar que el recolector de basura se encargue de esos rincones oscuros (ya que no hará mucha diferencia) mientras optimiza con mucho cuidado el área que se ejecuta en un circuito cerrado. Por lo tanto, puede elegir dónde optimizar y dónde no, y así puede enfocar su esfuerzo donde sea importante.
Ahora, si apaga completamente la recolección de basura, entonces no puede elegir. Debe deshacerse manualmente de cada objeto, nunca. ¿Se llama ese método como máximo una vez al día? En Java, puede dejarlo, ya que su impacto en el rendimiento es insignificante (puede estar bien dejar que ocurra un GC completo cada mes). En C ++, todavía está perdiendo recursos, por lo que debe cuidar incluso ese método oscuro. Por lo tanto, debe pagar el precio de la gestión de recursos en cada parte de su aplicación, mientras que en Java puede concentrarse.
Pero empeora.
¿Qué sucede si tiene un error, digamos en un rincón oscuro de su aplicación al que solo se accede el lunes en luna llena? Java tiene una fuerte garantía de seguridad. Hay poco o ningún "comportamiento indefinido". Si usa algo incorrecto, se genera una excepción, su programa se detiene y no se produce corrupción de datos. Así que estás bastante seguro de que nada malo puede suceder sin que te des cuenta.
Pero en algo como D, puede tener un mal acceso al puntero, o un desbordamiento del búfer, y puede dañar su memoria, pero su programa no lo sabrá (desactivó la seguridad, ¿recuerda?) Y seguirá funcionando con su incorrecto datos, y hacer algunas cosas bastante desagradables y corromper sus datos, y no lo sabe, y a medida que ocurre más corrupción, sus datos se vuelven cada vez más incorrectos, y de repente se rompen, y estaban en una aplicación crítica para la vida, y se produjo un error en el cálculo de un cohete, por lo que no funciona, explota el cohete y alguien muere, y su empresa está en la primera plana de cada periódico y su jefe le señala con el dedo que dice "Usted está El ingeniero que sugirió que usáramos D para optimizar el rendimiento, ¿por qué no pensó en la seguridad?". Y es tu culpa. Usted mató a esas personas con su estúpido intento en el rendimiento.
Ok, ok, la mayoría de las veces es mucho menos dramático que eso. Pero incluso una aplicación crítica para el negocio o simplemente una aplicación de GPS o, digamos, un sitio web de salud del gobierno puede tener algunas consecuencias bastante negativas si tiene errores. Usar un lenguaje que los prevenga por completo o que falle rápido cuando suceden suele ser una muy buena idea.
Hay un costo para desactivar una seguridad. Ser nativo no siempre tiene sentido. A veces es mucho más simple y seguro optimizar un poco un lenguaje seguro que utilizarlo todo para un idioma en el que puedas dispararte en el pie a lo grande. La corrección y la seguridad en muchos casos superan los pocos nanosegundos que habría desechado al eliminar el GC por completo. Disruptor se puede utilizar en esa situación, por lo que creo que LMAX-Exchange hizo la llamada correcta.
Pero, ¿qué pasa con D en particular? Tienes un GC si quieres para las esquinas oscuras, y el subconjunto SafeD (que no conocía antes de la edición) elimina el comportamiento indefinido (¡si recuerdas usarlo!).
Bueno, en ese caso es una simple cuestión de madurez. El ecosistema de Java está lleno de herramientas bien escritas y bibliotecas maduras (mejor para el desarrollo). Muchos más desarrolladores conocen Java que D (mejor para mantenimiento). Buscar un lenguaje nuevo y no tan popular para algo tan crítico como una aplicación financiera no hubiera sido una buena idea. Con un lenguaje menos conocido, si tiene un problema, pocos pueden ayudarlo, y las bibliotecas que encuentra tienden a tener más errores ya que estuvieron expuestos a menos personas.
Así que mi último punto aún es válido: si desea evitar problemas con consecuencias nefastas, quédese con opciones seguras. En este punto de la vida de D, sus clientes son las pequeñas empresas nuevas listas para asumir riesgos locos. Si un problema puede costar millones, es mejor mantenerse más lejos en la curva de la campana de la innovación .