Dos feeds, estrictamente en orden

Empate

Requisito

Una revisión de incidente necesita la cola del log de ayer seguida del log de hoy como una sola lista numerada — la primera entrada de hoy no debe aparecer nunca antes de la última de ayer. Los datos están en el código; las dos versiones deben imprimir las líneas que aparecen bajo Salida esperada.

Salida esperada
1. 23:41  cache flushed
2. 23:52  nightly backup started
3. 23:58  nightly backup finished
4. 00:04  cache warmed
5. 00:12  first request served
6. 06:30  daily report generated
7. 07:02  queue drained

Lado a lado

RxDart

FxDart

Por qué difieren

Ambas bibliotecas escriben «este feed, y luego aquel» como un solo operador, pero cada modelo garantiza el orden con su propio mecanismo. El concatWith de RxDart es un secuenciador de suscripciones: no se suscribe al stream de hoy hasta que el de ayer dispara done, así que el orden se mantiene incluso si ambas fuentes están vivas y la de hoy hubiera estado lista para emitir antes. El concat de FxDart es un secuenciador de demanda: la cadena tira del segundo iterable solo después de agotar el primero, y con dos listas en memoria eso es todo el orden que hay que organizar.

Ese hueco de mecanismo importa exactamente cuando las fuentes son genuinamente push — un stream que empieza a emitir en cuanto alguien se suscribe necesita la suscripción diferida de concatWith, donde un pipeline pull tendría primero que almacenar el feed aún no deseado. Sobre datos fijos los dos colapsan en las mismas siete líneas y el mismo map. Empate: el operador es vocabulario compartido, y cada modelo lo implementa con la herramienta que ya tenía.

Benchmark

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

N = 100

Tiempo Empate

RxDart 24 µs
FxDart 9.6 µs

Memoria pico Empate

RxDart 16.5 MB
FxDart 16.6 MB

N = 1,000,000

Tiempo Gana FxDart

RxDart 217.2 ms
FxDart 126.0 ms

Memoria pico Empate

RxDart 268.6 MB
FxDart 275.9 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í.