Revaluar el stock, tres consultas a la vez

Gana FxDart async

Requisito

Un almacén guarda artículos de stock, cada uno con un SKU, una cantidad disponible y un precio de libro. Refresca cada precio unitario desde un servicio de precios — como mucho tres consultas en vuelo —, recurriendo al precio de libro para los SKU que el servicio no conoce. Imprime el valor total revaluado del stock y cuántos artículos usaron el respaldo. El servicio se simula en el código de abajo con un retardo fijo; las dos versiones deben imprimir las líneas que aparecen bajo Salida esperada.

Salida esperada
stock value: $4280.10
fallback prices used: 2
max lookups in flight: 3

Lado a lado

Dart nativo

FxDart

Por qué difieren

Aquí se apilan dos partes difíciles. La consulta no puede perder su artículo — attach mantiene cada línea de stock junto al precio que devolvió el servicio (o null), que es lo que convierte el respaldo r.$2 ?? r.$1.bookPrice en una sola línea. Y el fan-out debe estar acotado — concurrent(3) es el límite como operador, ya que attach viaja sobre la misma maquinaria segura en paralelo que map. Los recuentos caen solos del vocabulario: sumBy para el total, countWhere para el conteo de respaldos.

La versión nativa tiene que construirlo todo: un pool de workers con cursor compartido para el límite, registros (artículo, precio) hechos a mano para que la entrada sobreviva el salto async, huecos de resultado predimensionados para conservar el orden, y una pasada de where(…).length para el conteo. Nada de eso es difícil — todo es ceremonia que entierra la tarea de cuatro pasos.

Benchmark

Apple M1 Max, 32 GB de RAM · Dart 3.12.2 (compilado AOT) · 2026-08-24

Caso async: la escala principal es N = 100,000, no 1,000,000. Cada elemento cuesta una vuelta del event loop en ambos lados, así que un millón de awaits reales mediría el event loop de Dart durante minutos — no el pipeline. Los retardos son de longitud cero y se conserva el límite de concurrencia del ejemplo; lo que comparan las barras es la maquinaria del pipeline.

N = 100

Tiempo Empate

Dart nativo 385 µs
FxDart 381 µs

Memoria pico Empate

Dart nativo 16.4 MB
FxDart 16.6 MB

N = 10,000

Tiempo Gana nativo

Dart nativo 30.5 ms
FxDart 34.1 ms

Memoria pico Gana FxDart

Dart nativo 49.0 MB
FxDart 31.1 MB

N = 100,000

Tiempo Gana nativo

Dart nativo 310.9 ms
FxDart 352.9 ms

Memoria pico Empate

Dart nativo 80.8 MB
FxDart 80.5 MB

Las barras son medianas de iteraciones cronometradas repetidas en procesos nuevos por lado (los N pequeños se agrupan por resolución del temporizador). Dos lados a menos del 5% entre sí — o a menos de 0.6 ms, una diferencia que nadie puede percibir — cuentan como empate; las carreras relativas ajustadas se vuelven a medir hasta 5 veces. En una app, cualquier cosa por debajo de unos pocos milisegundos es invisible para el usuario, gane la barra que gane. La memoria es el RSS pico del proceso. La VM de Dart y el dataset son idénticos en ambos lados, así que la diferencia entre las dos barras es lo que retiene el pipeline en sí.