15 puntos por ttyy1234 2024-11-29 | 10 comentarios | Compartir por WhatsApp

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

 
kroisse 2024-12-02

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 future que, 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í crea goroutine, 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.

 
bungker 2024-11-30

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.

 
roxie 2024-12-01

¿Podrías contar un poco más sobre la parte de compatibilidad? :eyes:

 
secret3056 2024-12-02

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".

 
bungker 2024-12-01

Escuché que la biblioteca msal de Microsoft no funciona en virtualthread.

 
vwjdalsgkv 2024-12-02

Creo que en el caso de la biblioteca msal que 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.

 
riki3 2024-12-02

¿Qué relación tiene con la seguridad de hilos? En primer lugar, goroutine no es un sistema que garantice la seguridad de hilos.

 
hookim 2024-11-30

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?

 
riki3 2024-11-30

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.

 
bungker 2024-11-30

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.