Detectar transacciones duplicadas
Requisito
Un cargo que aparece dos veces con el mismo comercio, importe y día es, probablemente, un doble pago. Encuentra cada grupo así en las transacciones de julio y lista cada transacción implicada para que el usuario pueda revisarlas, pero no marques el mismo comercio e importe en días distintos (un café que se repite no es un duplicado). Los datos están en el código de abajo; las dos versiones deben imprimir las líneas que aparecen bajo Salida esperada.
Salida esperada
Possible duplicate charges: 2026-07-08 Noodle Bar $18.90 2026-07-08 Noodle Bar $18.90 2026-07-21 StreamFlix $9.99 2026-07-21 StreamFlix $9.99
Lado a lado
Dart nativo
FxDart
Por qué difieren
El algoritmo es agrupar–conservar–aplanar, y FxDart lo escribe
exactamente con esas tres palabras: groupBy por la clave
comercio|importe|día, filter de los grupos con más de un
miembro, flatMap de los supervivientes de vuelta a
transacciones individuales (map + join les dan
formato). Dart nativo no tiene ninguna de las tres como vocabulario:
agrupar se convierte en un bucle con putIfAbsent, y
conservar-y-aplanar, en bucles for anidados con un
if entre medias. Ambas son correctas; solo una sigue
pareciéndose a la frase que la especificaba.
Benchmark
N = 100
Tiempo Empate
Memoria pico Empate
N = 10,000
Tiempo Empate
Memoria pico Gana FxDart
N = 1,000,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í.