Detectar transacciones duplicadas

Gana FxDart

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

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

N = 100

Tiempo Empate

Dart nativo 50 µs
FxDart 42 µs

Memoria pico Empate

Dart nativo 16.5 MB
FxDart 16.5 MB

N = 10,000

Tiempo Empate

Dart nativo 4.17 ms
FxDart 3.86 ms

Memoria pico Gana FxDart

Dart nativo 40.2 MB
FxDart 36.0 MB

N = 1,000,000

Tiempo Empate

Dart nativo 977.4 ms
FxDart 966.1 ms

Memoria pico Empate

Dart nativo 324.6 MB
FxDart 332.5 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í.