¿Cuánta memoria necesitas en 2024 para ejecutar 1 millón de tareas concurrentes?
(hez2010.github.io)Se ejecutaron programas con versiones recientes de Rust, C#, Python, Go, Java y NodeJS, entre otros, que procesan 1 millón de tareas concurrentes, para comparar su eficiencia de memoria.
C# (NativeAOT) y Rust mostraron la mejor eficiencia de memoria, mientras que Go recibió una evaluación baja por un consumo de memoria mayor de lo esperado. En general, el rendimiento de .NET y Rust destacó, y Java (GraalVM) mostró una mejora sorprendente.
En concreto, Rust usó la menor cantidad de memoria con unos 29MB, seguido por C# NativeAOT con unos 71MB. NodeJS registró 232MB y Python 339MB. Go mostró un uso de memoria relativamente alto con 753MB, dejando un resultado decepcionante. Java (GraalVM) mostró una gran mejora con 92MB.
10 comentarios
Al ver el código del benchmark, en los casos de Rust y Python parece que en realidad no se crean tareas concurrentes, sino solo objetos
futureque, aunque son asíncronos, no pueden ejecutarse en paralelo con otras tareas. Supongo que C# probablemente sea un caso parecido. En cambio, el código de Go sí creagoroutine, que son tareas con su propio call stack y demás, así que me parece que esa podría ser la razón por la que el uso de memoria de Go se dispara de forma tan notable en el caso de 1 millón.Para defender a Go, funciona aunque haya cualquier biblioteca dentro de un millón de funciones ejecutándose. Solo hay que poner
go. En otros lenguajes basados en asincronía, si en medio hay una biblioteca con funcionamiento síncrono que consume aunque sea un poco de tiempo, termina por comerse todas las ventajas de la asincronía, y se vuelve una situación desesperante.Para aprovechar al 100% las ventajas de la asincronía, hay que convertir a asíncronas todas las funciones que consuman aunque sea un poco de tiempo.
Los Virtual Threads de Java... mmm, esta vez en nuestra empresa intentamos apostar por los Virtual Threads de Java, pero por problemas de compatibilidad con bibliotecas al final tuvimos que volver a hilos normales, y el desenlace fue terminar levantando decenas de instancias.
¿Podrías contar un poco más sobre la parte de compatibilidad? :eyes:
Se podría decir que ya no existe tanto esa idea común en Spring de que "para usar WebFlux correctamente, en lugar de JPA hay que usarlo con R2DBC para que realmente muestre su valor".
Escuché que la biblioteca msal de Microsoft no funciona en
virtualthread.Creo que en el caso de la biblioteca
msalque puso como ejemplo, en Go también sería el mismo caso si es una biblioteca que usa tipos de datos o estructuras que no son thread-safe.¿Qué relación tiene con la seguridad de hilos? En primer lugar,
goroutineno es un sistema que garantice la seguridad de hilos.Gracias por la información
Tengo una pregunta.
Entonces, en otros lenguajes aparte de Go, ¿si hay una biblioteca de estilo síncrono como mencionaste, todo termina rompiéndose?
¿O quizás entre otros lenguajes también hay alguno que, como Go, soporte asincronía completa?
Existe una expresión,
colorless. Go es el único lenguaje en el que no hace falta distinguir entre asincronía y sincronía. Desde la perspectiva del usuario, cuando se programa con necesidad de concurrencia, Go tiene una ventaja abrumadora en términos de dificultad y usabilidad.Aunque en rendimiento quizá quede un poco por detrás de una programación asíncrona optimizada.
Perdón por la corrección, pero solo voy a señalar las partes incorrectas de las expresiones "se rompe" y "asincronía perfecta". En programación asíncrona también está bien usar librerías síncronas, siempre que haya garantía de que se completarán en poco tiempo. El problema aparece cuando hay llamadas de larga duración ejecutadas de forma síncrona, porque retrasan el procesamiento de otras tareas asíncronas.
En Go no existe el concepto de asincronía como parte del lenguaje mismo, porque se pueden asignar cientos de millones de tareas usando goroutines. Desde el punto de vista de quien programa, es muy cómodo porque cualquier función puede ejecutarse en paralelo simplemente llamándola con
go.Personalmente, creo que la "asincronía perfecta" quizá sea JavaScript, cuyo fundamento a nivel de lenguaje sí es la asincronía.