todos-contra-el-fuego-web/bench/treeUnionWorker.js
vjrj 072e76aaed bench(union): banco de carga de la unión de suscripciones
Ejecuta el worker de producción contra suscripciones sintéticas realistas
(península, Canarias, Baleares; radios de 5 a 100 km) y mide lo que la fase 12
pide: duración del recreate completo y del incrementalAdd, retraso máximo del
event loop del proceso padre —que es donde vive DDP y por tanto la pregunta
real de "¿se congela la web?"—, tamaño del documento frente al límite de 16 MiB
y pico de RSS.

`--spread world` reparte las suscripciones por todo el mundo: es el peor caso
para el tamaño, porque casi no se solapan y la unión conserva un polígono por
suscripción en vez de fundirlos.

treeUnionWorker.js es una variante solo del banco (une en árbol en vez de en
cadena) para poder comparar estrategias con números antes de tocar el worker
de verdad. El worker de producción solo cambia en que ahora acepta `steps` por
workerData, con el mismo 144 de siempre por defecto.
2026-08-01 21:51:27 +02:00

49 lines
1.8 KiB
JavaScript

// Variante SOLO PARA EL BANCO DE CARGA del worker de uniones.
//
// El worker de producción une en cadena: `u = union(u, c[i])` para cada círculo.
// Eso hace que cada llamada trabaje sobre un polígono que no para de crecer, así
// que el coste crece mucho más deprisa que el número de suscripciones. Esta
// variante une en árbol (pares, luego pares de pares…): el mismo resultado
// geométrico, pero la mayoría de las uniones son entre polígonos pequeños.
//
// Está aquí, y no en private/, para que no acabe en el bundle: es material de
// medición. Si los números lo justifican, se porta al worker de verdad.
const { parentPort, workerData } = require('worker_threads');
// eslint-disable-next-line import/no-dynamic-require
const tcircle = require(workerData.turfPaths.circle).default;
// eslint-disable-next-line import/no-dynamic-require
const tunion = require(workerData.turfPaths.union).default;
// eslint-disable-next-line import/no-dynamic-require
const ttrunc = require(workerData.turfPaths.truncate).default;
const truncOptions = { precision: 6, coordinates: 2 };
const run = () => {
const { subs, baseUnion, steps } = workerData;
let level = subs.map(s => ttrunc(tcircle(
[s.location.lon, s.location.lat],
s.distance,
{ units: 'kilometers', steps: steps || 144 }
), truncOptions));
if (level.length === 0) return baseUnion || null;
while (level.length > 1) {
const next = [];
for (let i = 0; i < level.length; i += 2) {
if (i + 1 < level.length) next.push(ttrunc(tunion(level[i], level[i + 1]), truncOptions));
else next.push(level[i]);
}
level = next;
}
return baseUnion ? ttrunc(tunion(baseUnion, level[0]), truncOptions) : level[0];
};
try {
parentPort.postMessage({ union: run() });
} catch (e) {
parentPort.postMessage({ error: e.message });
}