/** Medición local reproducible; no acredita rendimiento de navegador, red o producción. */ import assert from "node:assert/strict"; import { performance } from "node:perf_hooks"; import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { EntityTable } from "../components/entity-list.tsx"; import { createTextMatcher } from "./text-search.ts"; function measure(operation, iterations) { for (let index = 0; index < 5; index++) { operation(); } const samples = []; for (let index = 0; index < iterations; index++) { const started = performance.now(); operation(); samples.push(performance.now() - started); } samples.sort((first, second) => first - second); return { medianMs: samples[Math.floor(samples.length / 2)], maxMs: samples.at(-1), iterations }; } const results = []; const columns = [ { id: "name", label: "Nombre", value: (item) => item.name, render: (item) => item.name }, ]; for (const count of [30, 300, 1000]) { const items = Array.from({ length: count }, (_, index) => ({ id: String(index), name: `${index % 2 ? "Portátil Administración Peña" : "Sobremesa Ingeniería Pena"} PC-${index}`, })); const matches = createTextMatcher(" portatil "); const filtered = items.filter((item) => matches(item.name)); assert.equal(filtered.length, count / 2); results.push({ count, matches: filtered.length, filter: measure(() => items.filter((item) => matches(item.name)), 100), previousComparison: measure( () => items.filter((item) => item.name.toLowerCase().includes("portátil")), 100 ), ssrTable: measure( () => renderToStaticMarkup( createElement(EntityTable, { items, columns, title: "Equipos", search: "portatil", }) ), 10 ), }); } process.stdout.write(`${JSON.stringify({ runtime: process.version, results }, null, 2)}\n`);