X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=benchmarks%2Fbenchmarks-utils.mjs;h=79971825e20e9e66c394b7b229eb6b4b5d852eaf;hb=3aa16da67d1de7ed79de0fa4eedccc9cc7f58a52;hp=e8c67583bf1958d7f2f0a2294bd2f1c399ca9b49;hpb=8ebe6c308dc1fc3202980126da043b2855d24780;p=poolifier.git diff --git a/benchmarks/benchmarks-utils.mjs b/benchmarks/benchmarks-utils.mjs index e8c67583..79971825 100644 --- a/benchmarks/benchmarks-utils.mjs +++ b/benchmarks/benchmarks-utils.mjs @@ -1,17 +1,68 @@ import crypto from 'node:crypto' +import assert from 'node:assert' import fs from 'node:fs' +import Benchmark from 'benchmark' import { DynamicClusterPool, DynamicThreadPool, FixedClusterPool, FixedThreadPool, + Measurements, PoolTypes, + WorkerChoiceStrategies, WorkerTypes } from '../lib/index.mjs' import { TaskFunctions } from './benchmarks-types.mjs' -export const runTest = async (pool, { taskExecutions, workerData }) => { - return new Promise((resolve, reject) => { +export const buildPoolifierPool = ( + workerType, + poolType, + poolSize, + poolOptions +) => { + switch (poolType) { + case PoolTypes.fixed: + switch (workerType) { + case WorkerTypes.thread: + return new FixedThreadPool( + poolSize, + './benchmarks/internal/thread-worker.mjs', + poolOptions + ) + case WorkerTypes.cluster: + return new FixedClusterPool( + poolSize, + './benchmarks/internal/cluster-worker.mjs', + poolOptions + ) + } + break + case PoolTypes.dynamic: + switch (workerType) { + case WorkerTypes.thread: + return new DynamicThreadPool( + Math.floor(poolSize / 2), + poolSize, + './benchmarks/internal/thread-worker.mjs', + poolOptions + ) + case WorkerTypes.cluster: + return new DynamicClusterPool( + Math.floor(poolSize / 2), + poolSize, + './benchmarks/internal/cluster-worker.mjs', + poolOptions + ) + } + break + } +} + +export const runPoolifierPool = async ( + pool, + { taskExecutions, workerData } +) => { + return await new Promise((resolve, reject) => { let executions = 0 for (let i = 1; i <= taskExecutions; i++) { pool @@ -19,18 +70,109 @@ export const runTest = async (pool, { taskExecutions, workerData }) => { .then(() => { ++executions if (executions === taskExecutions) { - return resolve({ ok: 1 }) + resolve({ ok: 1 }) } return null }) - .catch((err) => { + .catch(err => { console.error(err) - return reject(err) + reject(err) }) } }) } +export const runPoolifierPoolBenchmark = async ( + name, + pool, + { taskExecutions, workerData } +) => { + return await new Promise((resolve, reject) => { + try { + const suite = new Benchmark.Suite(name) + for (const workerChoiceStrategy of Object.values( + WorkerChoiceStrategies + )) { + for (const enableTasksQueue of [false, true]) { + if (workerChoiceStrategy === WorkerChoiceStrategies.FAIR_SHARE) { + for (const measurement of [ + Measurements.runTime, + Measurements.elu + ]) { + suite.add( + `${name} with ${workerChoiceStrategy}, with ${measurement} and ${ + enableTasksQueue ? 'with' : 'without' + } tasks queue`, + async () => { + pool.setWorkerChoiceStrategy(workerChoiceStrategy, { + measurement + }) + pool.enableTasksQueue(enableTasksQueue) + assert.strictEqual( + pool.opts.workerChoiceStrategy, + workerChoiceStrategy + ) + assert.strictEqual( + pool.opts.enableTasksQueue, + enableTasksQueue + ) + assert.strictEqual( + pool.opts.workerChoiceStrategyOptions.measurement, + measurement + ) + await runPoolifierPool(pool, { + taskExecutions, + workerData + }) + } + ) + } + } else { + suite.add( + `${name} with ${workerChoiceStrategy} and ${ + enableTasksQueue ? 'with' : 'without' + } tasks queue`, + async () => { + pool.setWorkerChoiceStrategy(workerChoiceStrategy) + pool.enableTasksQueue(enableTasksQueue) + assert.strictEqual( + pool.opts.workerChoiceStrategy, + workerChoiceStrategy + ) + assert.strictEqual(pool.opts.enableTasksQueue, enableTasksQueue) + await runPoolifierPool(pool, { + taskExecutions, + workerData + }) + } + ) + } + } + } + suite + .on('cycle', event => { + console.info(event.target.toString()) + }) + .on('complete', async function () { + console.info( + 'Fastest is ' + + LIST_FORMATTER.format(this.filter('fastest').map('name')) + ) + await pool.destroy() + resolve() + }) + .run({ async: true }) + } catch (error) { + reject(error) + } + }) +} + +export const LIST_FORMATTER = new Intl.ListFormat('en-US', { + style: 'long', + type: 'conjunction' +}) + export const generateRandomInteger = ( max = Number.MAX_SAFE_INTEGER, min = 0 @@ -46,7 +188,7 @@ export const generateRandomInteger = ( return Math.floor(Math.random() * (max + 1)) } -const jsonIntegerSerialization = (n) => { +const jsonIntegerSerialization = n => { for (let i = 0; i < n; i++) { const o = { a: i @@ -61,7 +203,7 @@ const jsonIntegerSerialization = (n) => { * @param {number} n - The number of fibonacci numbers to generate. * @returns {number} - The nth fibonacci number. */ -const fibonacci = (n) => { +const fibonacci = n => { if (n <= 1) return n return fibonacci(n - 1) + fibonacci(n - 2) } @@ -71,7 +213,7 @@ const fibonacci = (n) => { * @param {number} n - The number to calculate the factorial of. * @returns {number} - The factorial of n. */ -const factorial = (n) => { +const factorial = n => { if (n === 0) { return 1 } @@ -100,7 +242,7 @@ const readWriteFiles = ( return { ok: 1 } } -export const executeTaskFunction = (data) => { +export const executeTaskFunction = data => { switch (data.function) { case TaskFunctions.jsonIntegerSerialization: return jsonIntegerSerialization(data.taskSize || 1000) @@ -114,42 +256,3 @@ export const executeTaskFunction = (data) => { throw new Error('Unknown task function') } } - -export const buildPool = (workerType, poolType, poolSize, poolOptions) => { - switch (poolType) { - case PoolTypes.fixed: - switch (workerType) { - case WorkerTypes.thread: - return new FixedThreadPool( - poolSize, - './benchmarks/internal/thread-worker.mjs', - poolOptions - ) - case WorkerTypes.cluster: - return new FixedClusterPool( - poolSize, - './benchmarks/internal/cluster-worker.mjs', - poolOptions - ) - } - break - case PoolTypes.dynamic: - switch (workerType) { - case WorkerTypes.thread: - return new DynamicThreadPool( - Math.floor(poolSize / 2), - poolSize, - './benchmarks/internal/thread-worker.mjs', - poolOptions - ) - case WorkerTypes.cluster: - return new DynamicClusterPool( - Math.floor(poolSize / 2), - poolSize, - './benchmarks/internal/cluster-worker.mjs', - poolOptions - ) - } - break - } -}