Media móvil de tres lecturas
Requisito
Suaviza ocho lecturas horarias de temperatura con una media móvil de tres lecturas: para cada ventana de 3 lecturas consecutivas, imprime la ventana y su media a un decimal — seis ventanas completas, sin parciales. Los datos están en el código; las dos versiones deben imprimir las líneas que aparecen bajo Salida esperada.
Salida esperada
21.0 21.6 22.4 -> avg 21.7 21.6 22.4 23.1 -> avg 22.4 22.4 23.1 22.8 -> avg 22.8 23.1 22.8 22.2 -> avg 22.7 22.8 22.2 21.9 -> avg 22.3 22.2 21.9 21.4 -> avg 21.8
Lado a lado
RxDart
FxDart
Por qué difieren
RxDart escribe una ventana deslizante como una parametrización del
loteo: bufferCount(3, 1) — búferes de tres, con un búfer
nuevo empezando cada evento. Funciona, pero la codificación gotea dos
veces. Tienes que saber que el segundo argumento es
startBufferEvery y que 1 significa
«deslizante»; y al final del stream el operador vuelca sus búferes aún
abiertos, así que un parcial de bajada como [21.9, 21.4]
también sale, y un where((w) => w.length == 3) tiene
que montar guardia por un caso que el requisito nunca mencionó.
FxDart tiene una palabra para el concepto en sí:
windowed(3) produce exactamente las ventanas completas, y
partial: true es la aceptación explícita de la bajada —
el valor por defecto coincide con lo que una media móvil significa.
Añade average como función de la biblioteca (RxDart no
tiene helpers de agregación, así que la media es un
reduce-y-divide hecho a mano) y el lado pull declara el
requisito mientras el lado push lo codifica. Ese hueco es de
vocabulario, no de modelo — pero el vocabulario existe porque las
ventanas sobre un iterable son una idea nativa del pull, y este se lo
lleva FxDart.
Benchmark
N = 100
Tiempo Empate
Memoria pico Empate
N = 1,000,000
Tiempo Gana FxDart
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í.