Un stream alimenta un pipeline tipado
Requisito
Un feed de logs en vivo emite siete líneas con un calendario fijo y se cierra. Conserva solo los warnings, ponlos en mayúsculas para el canal de incidentes, e imprímelos con un conteo final. El feed está simulado en el código (de forma idéntica en ambos lados); las dos versiones deben imprimir las líneas que aparecen bajo Salida esperada.
Salida esperada
WARN: DISK 81% FULL WARN: LATENCY 900MS WARN: RETRY QUEUE AT 12 warnings: 3
Lado a lado
RxDart
FxDart
Por qué difieren
Apenas difieren — y ese es el sentido de este par. La fuente es una
cosa nativa del push, un Stream que emite cuando le
place, y RxDart se queda en ese modelo: mapNotNull
filtra y formatea en un operador, toList recoge al
cierre. Limpio, idiomático, listo.
El lado FxDart no pelea contra el stream ni re-modela la fuente — le
tiende un puente. fxStream envuelve cualquier
Stream como un iterable async basado en pull, y a partir
de ahí el código es la misma cadena tipada que escribirías sobre una
lista: filter, map, toList. El
puente guarda en buffer los eventos empujados hasta que el pipeline
los demanda, así que nada se pierde y el orden se conserva. Este es
un ejemplo de cooperación, no de contienda: deja que el stream sea un
stream en el borde donde nacen los eventos, y cruza a un pipeline
pull en el momento en que quieras procesamiento tipado y dirigido por
demanda — los dos modelos se componen en una línea. Empate, y
deliberadamente.
Benchmark
Caso async: la escala principal es N = 10,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 Empate
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í.