Diff de dos snapshots de un libro de cuentas

Gana FxDart

Requisito

Dos snapshots del mismo libro de cuentas (los datos están en el código): entre uno y otro hubo una sincronización, y se añadieron y eliminaron entradas. Imprime un diff basado en el id de cada entrada —líneas + para las entradas añadidas y - para las eliminadas (cada sección ordenada por id), el número de entradas sin cambios y la variación neta del importe total. Ambas versiones deben imprimir el diff que aparece bajo Salida esperada.

Salida esperada
Ledger diff (5 -> 5 entries)
+ t6 Noodle Bar $18.90
+ t7 Pharmacy $22.40
- t3 Metro card $30.00
- t4 Cinema $15.00
= 3 unchanged entries
Net change: -$3.70

Lado a lado

Dart nativo

FxDart

Por qué difieren

Hacer un diff es álgebra de conjuntos sobre una clave, y FxDart trae ese vocabulario de serie: llamar a differenceBy en los dos sentidos da lo añadido y lo eliminado, e intersectionBy da las entradas sin cambios —tres declaraciones que se leen como la definición misma de un diff. El pipeline sortBymapconcat renderiza después las dos secciones en una sola expresión. Dart nativo solo tiene operaciones de conjuntos para el propio Set, no para «por esta clave de estos objetos», así que la versión honesta proyecta a mano los conjuntos de id y escribe un filtro contains negado por cada sentido —fácil de invertir sin querer, y la intención («¿qué hay en B que no esté en A?») acaba viviendo en la polaridad del predicado en lugar de en el nombre de una función.

Benchmark

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

N = 100

Tiempo Empate

Dart nativo 21 µs
FxDart 23 µs

Memoria pico Empate

Dart nativo 16.5 MB
FxDart 16.5 MB

N = 10,000

Tiempo Gana nativo

Dart nativo 2.37 ms
FxDart 3.16 ms

Memoria pico Gana nativo

Dart nativo 26.0 MB
FxDart 31.2 MB

N = 500,000

Tiempo Gana nativo

Dart nativo 223.4 ms
FxDart 261.0 ms

Memoria pico Gana FxDart

Dart nativo 182.1 MB
FxDart 171.8 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í.