Revaluar el stock, tres consultas a la vez
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
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
Memoria pico Empate
N = 10,000
Tiempo Gana nativo
Memoria pico Gana FxDart
N = 100,000
Tiempo Gana nativo
Memoria pico Empate
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í.