Latencia p50/p95 por endpoint

Gana FxDart

Requisito

A partir de logs de peticiones en crudo (los datos están en el código), descarta las peticiones fallidas y calcula la latencia p50 y p95 por endpoint: ordena las latencias de cada endpoint y toma el valor situado en el índice round((n-1) * q / 100). Imprime una tabla ordenada por el peor p95 primero y luego señala el peor endpoint. Las dos versiones deben imprimir la tabla que aparece bajo Salida esperada.

Salida esperada
Latency percentiles (successful requests only)
  /orders  p50 133 ms  p95 620 ms  (5 reqs)
  /search  p50 210 ms  p95 480 ms  (4 reqs)
  /users   p50  88 ms  p95 340 ms  (5 reqs)
Worst p95: /orders at 620 ms

Lado a lado

Dart nativo

FxDart

Por qué difieren

Un percentil es «ordena y luego indexa»: en FxDart eso es literalmente sortBy + nth, aplicados dentro de un pipeline groupBymap que convierte cada grupo de endpoint en una fila de estadísticas; ordenar la tabla y encontrar el peor endpoint reutilizan esas mismas filas con sortBy y maxBy. La versión nativa hace las mismas cuentas, pero a través de una lista mutable de filas rellenada en un bucle for, un ..sort() in situ, acceso por índice en crudo y un comparador con reduce para el máximo. Ambas son correctas; el lado de fxdart mantiene «agrupar → resumir → ordenar» como tres trazos visibles en lugar de un solo bucle que hace los tres a la vez.

Benchmark

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

N = 100

Tiempo Empate

Dart nativo 22 µs
FxDart 20 µs

Memoria pico Empate

Dart nativo 16.6 MB
FxDart 16.5 MB

N = 10,000

Tiempo Empate

Dart nativo 1.93 ms
FxDart 1.80 ms

Memoria pico Gana FxDart

Dart nativo 18.1 MB
FxDart 17.3 MB

N = 1,000,000

Tiempo Empate

Dart nativo 204.7 ms
FxDart 209.7 ms

Memoria pico Gana nativo

Dart nativo 139.4 MB
FxDart 192.2 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í.