concurrent o parallel

Dos maneras de solapar trabajo. No son el mismo operador con dos nombres.

FxAsync<T> FxAsync.concurrent(int length) FxAsync<R> Fx.parallel(int workers, FutureOr<R> Function(T input) worker) FxAsync<R> Fx.mapConcurrent(int concurrency, FutureOr<R> Function(T a) f) FxAsync<R> Fx.mapParallel(int workers, FutureOr<R> Function(T input) worker)

Lección

concurrent(n) solapa Futures en este isolate — I/O, espera. parallel(n, worker) solapa trabajo de CPU entre otros isolates. Elige según en qué gasta el tiempo el callback, no según cuánto quieras «ir más rápido».

concurrent(n)parallel(n)
Qué se solapaFutures en este isolateisolates worker
Callbackcualquier closurefunción top-level o static
Valorescualquier cosaenviables
PlataformasVM, Flutter, websolo VM / Flutter
Trabajo barato (x + 1, Future.delayed(0))un marcador; los hops son baratosun mensaje de isolate por elemento — casi siempre una pérdida
El trabajo adecuadoHTTP, DB, archivos, awaitparseo JSON, imágenes, crypto, un bucle apretado

I/O es sobre todo espera. Mientras una petición está en vuelo el isolate está idle, así que solapar cuatro Futures con concurrent(4) recorta el tiempo de reloj y no necesita otro isolate. El trabajo de CPU es el isolate: bloquea el event loop (y un frame de Flutter) hasta que vuelve. Para eso está parallel.

El hop de isolate no es gratis. Cada elemento se serializa, se envía, se ejecuta, se serializa de vuelta y se reordena. Un callback cuyo cuerpo es x + 1 gasta más tiempo en ese hop que en la suma — cuatro workers entonces lo hacen más lento que uno, porque pagas cuatro veces el porte sin CPU que recuperar. Medido: mil x + 1 con cuatro workers tardaron aproximadamente el doble que con uno; un bucle apretado de 20000 iteraciones con cuatro workers fue aproximadamente el doble de rápido que con uno. Si el trabajo no es más pesado que el hop, quédate en este isolate.

// I/O — overlap Futures here
fx(ids).mapConcurrent(8, fetchUser);

// CPU — only when the body is heavy enough
fx(blobs).parallel(parallelWorkers, parseJson);

// This is a loss. The hop is bigger than the work.
fx(nums).parallel(4, (x) => x + 1);
Relacionado: concurrent — I/O, cualquier closure · mapConcurrent — la forma combinada de I/O · parallel — CPU, worker enviable · mapParallel — alias de parallel