From 149fdbb9ad4a54f2a96409f2fe68b73c66149729 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 23 Jul 2023 19:05:38 +0200 Subject: [PATCH] perf: automatically cover most poolifier settings in benchmark MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Close #779 Signed-off-by: Jérôme Benoit --- benchmarks/benchmarks-types.mjs | 14 +- benchmarks/internal/bench.mjs | 391 ++++---------------------------- src/pools/worker.ts | 4 +- 3 files changed, 51 insertions(+), 358 deletions(-) diff --git a/benchmarks/benchmarks-types.mjs b/benchmarks/benchmarks-types.mjs index cbd254e0..dcffd136 100644 --- a/benchmarks/benchmarks-types.mjs +++ b/benchmarks/benchmarks-types.mjs @@ -1,16 +1,10 @@ -export const WorkerFunctions = { +import { PoolTypes, WorkerTypes } from '../lib/index.mjs' + +const WorkerFunctions = { jsonIntegerSerialization: 'jsonIntegerSerialization', fibonacci: 'fibonacci', factorial: 'factorial', readWriteFiles: 'readWriteFiles' } -export const PoolTypes = { - fixed: 'fixed', - dynamic: 'dynamic' -} - -export const WorkerTypes = { - thread: 'thread', - cluster: 'cluster' -} +export { PoolTypes, WorkerFunctions, WorkerTypes } diff --git a/benchmarks/internal/bench.mjs b/benchmarks/internal/bench.mjs index 26cc81c3..1fbcc5aa 100644 --- a/benchmarks/internal/bench.mjs +++ b/benchmarks/internal/bench.mjs @@ -1,4 +1,4 @@ -import Benchmark from 'benny' +import { add, complete, cycle, save, suite } from 'benny' import { WorkerChoiceStrategies, availableParallelism @@ -11,372 +11,71 @@ import { import { buildPool, runTest } from '../benchmarks-utils.mjs' const poolSize = availableParallelism() +const pools = [] +for (const poolType of Object.values(PoolTypes)) { + for (const workerType of Object.values(WorkerTypes)) { + for (const workerChoiceStrategy of Object.values(WorkerChoiceStrategies)) { + for (const tasksQueue of [false, true]) { + const pool = buildPool( + workerType, + poolType, + poolSize, + tasksQueue + ? { + ...{ + workerChoiceStrategy + }, + ...{ enableTasksQueue: true } + } + : { + workerChoiceStrategy + } + ) + pools.push([ + `${poolType}:${workerType}:${workerChoiceStrategy}:${tasksQueue}`, + pool + ]) + } + } + } +} const taskExecutions = 1 const workerData = { function: WorkerFunctions.jsonIntegerSerialization, taskSize: 1000 } -const tasksQueuePoolOption = { enableTasksQueue: true } -const workerChoiceStrategyRoundRobinPoolOption = { - workerChoiceStrategy: WorkerChoiceStrategies.ROUND_ROBIN -} -const workerChoiceStrategyLeastUsedPoolOption = { - workerChoiceStrategy: WorkerChoiceStrategies.LEAST_USED -} -const workerChoiceStrategyLeastBusyPoolOption = { - workerChoiceStrategy: WorkerChoiceStrategies.LEAST_BUSY -} -const workerChoiceStrategyWeightedRoundRobinPoolOption = { - workerChoiceStrategy: WorkerChoiceStrategies.WEIGHTED_ROUND_ROBIN -} -const workerChoiceStrategyFairSharePoolOption = { - workerChoiceStrategy: WorkerChoiceStrategies.FAIR_SHARE -} - -const fixedThreadPoolRoundRobin = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyRoundRobinPoolOption -) - -const fixedThreadPoolRoundRobinTasksQueue = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - { ...workerChoiceStrategyRoundRobinPoolOption, ...tasksQueuePoolOption } -) - -const fixedThreadPoolLeastUsed = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyLeastUsedPoolOption -) - -const fixedThreadPoolLeastBusy = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyLeastBusyPoolOption -) - -const fixedThreadPoolWeightedRoundRobin = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyWeightedRoundRobinPoolOption -) - -const fixedThreadPoolFairShare = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyFairSharePoolOption -) - -const fixedThreadPoolFairShareTasksQueue = buildPool( - WorkerTypes.thread, - PoolTypes.fixed, - poolSize, - { ...workerChoiceStrategyFairSharePoolOption, ...tasksQueuePoolOption } -) - -const dynamicThreadPoolRoundRobin = buildPool( - WorkerTypes.thread, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyRoundRobinPoolOption -) - -const dynamicThreadPoolLeastUsed = buildPool( - WorkerTypes.thread, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyLeastUsedPoolOption -) - -const dynamicThreadPoolLeastBusy = buildPool( - WorkerTypes.thread, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyLeastBusyPoolOption -) - -const dynamicThreadPoolWeightedRoundRobin = buildPool( - WorkerTypes.thread, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyWeightedRoundRobinPoolOption -) -const dynamicThreadPoolFairShare = buildPool( - WorkerTypes.thread, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyFairSharePoolOption -) - -const fixedClusterPoolRoundRobin = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyRoundRobinPoolOption -) - -const fixedClusterPoolRoundRobinTasksQueue = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - { ...workerChoiceStrategyRoundRobinPoolOption, ...tasksQueuePoolOption } -) - -const fixedClusterPoolLeastUsed = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyLeastUsedPoolOption -) - -const fixedClusterPoolLeastBusy = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyLeastBusyPoolOption -) - -const fixedClusterPoolWeightedRoundRobin = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyWeightedRoundRobinPoolOption -) - -const fixedClusterPoolFairShare = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - workerChoiceStrategyFairSharePoolOption -) - -const fixedClusterPoolFairShareTaskQueue = buildPool( - WorkerTypes.cluster, - PoolTypes.fixed, - poolSize, - { ...workerChoiceStrategyFairSharePoolOption, ...tasksQueuePoolOption } -) - -const dynamicClusterPoolRoundRobin = buildPool( - WorkerTypes.cluster, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyRoundRobinPoolOption -) - -const dynamicClusterPoolLeastUsed = buildPool( - WorkerTypes.cluster, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyLeastUsedPoolOption -) - -const dynamicClusterPoolLeastBusy = buildPool( - WorkerTypes.cluster, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyLeastBusyPoolOption -) - -const dynamicClusterPoolWeightedRoundRobin = buildPool( - WorkerTypes.cluster, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyWeightedRoundRobinPoolOption -) - -const dynamicClusterPoolFairShare = buildPool( - WorkerTypes.cluster, - PoolTypes.dynamic, - poolSize, - workerChoiceStrategyFairSharePoolOption -) +const addPools = pools => + pools.map(([name, pool]) => { + return add(name, async () => { + await runTest(pool, { + taskExecutions, + workerData + }) + }) + }) const resultsFile = 'poolifier' const resultsFolder = 'benchmarks/internal/results' -Benchmark.suite( +suite( 'Poolifier', - Benchmark.add('Fixed:ThreadPool:RoundRobin', async () => { - await runTest(fixedThreadPoolRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add( - 'Fixed:ThreadPool:RoundRobin:{ enableTasksQueue: true }', - async () => { - await runTest(fixedThreadPoolRoundRobinTasksQueue, { - taskExecutions, - workerData - }) - } - ), - Benchmark.add('Fixed:ThreadPool:LeastUsed', async () => { - await runTest(fixedThreadPoolLeastUsed, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ThreadPool:LeastBusy', async () => { - await runTest(fixedThreadPoolLeastBusy, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ThreadPool:WeightedRoundRobin', async () => { - await runTest(fixedThreadPoolWeightedRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ThreadPool:FairShare', async () => { - await runTest(fixedThreadPoolFairShare, { - taskExecutions, - workerData - }) - }), - Benchmark.add( - 'Fixed:ThreadPool:FairShare:{ enableTasksQueue: true }', - async () => { - await runTest(fixedThreadPoolFairShareTasksQueue, { - taskExecutions, - workerData - }) - } - ), - Benchmark.add('Dynamic:ThreadPool:RoundRobin', async () => { - await runTest(dynamicThreadPoolRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ThreadPool:LeastUsed', async () => { - await runTest(dynamicThreadPoolLeastUsed, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ThreadPool:LeastBusy', async () => { - await runTest(dynamicThreadPoolLeastBusy, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ThreadPool:WeightedRoundRobin', async () => { - await runTest(dynamicThreadPoolWeightedRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ThreadPool:FairShare', async () => { - await runTest(dynamicThreadPoolFairShare, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ClusterPool:RoundRobin', async () => { - await runTest(fixedClusterPoolRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add( - 'Fixed:ClusterPool:RoundRobin:{ enableTasksQueue: true }', - async () => { - await runTest(fixedClusterPoolRoundRobinTasksQueue, { - taskExecutions, - workerData - }) - } - ), - Benchmark.add('Fixed:ClusterPool:LeastUsed', async () => { - await runTest(fixedClusterPoolLeastUsed, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ClusterPool:LeastBusy', async () => { - await runTest(fixedClusterPoolLeastBusy, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ClusterPool:WeightedRoundRobin', async () => { - await runTest(fixedClusterPoolWeightedRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Fixed:ClusterPool:FairShare', async () => { - await runTest(fixedClusterPoolFairShare, { - taskExecutions, - workerData - }) - }), - Benchmark.add( - 'Fixed:ClusterPool:FairShare:{ enableTasksQueue: true }', - async () => { - await runTest(fixedClusterPoolFairShareTaskQueue, { - taskExecutions, - workerData - }) - } - ), - Benchmark.add('Dynamic:ClusterPool:RoundRobin', async () => { - await runTest(dynamicClusterPoolRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ClusterPool:LeastUsed', async () => { - await runTest(dynamicClusterPoolLeastUsed, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ClusterPool:LeastBusy', async () => { - await runTest(dynamicClusterPoolLeastBusy, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ClusterPool:WeightedRoundRobin', async () => { - await runTest(dynamicClusterPoolWeightedRoundRobin, { - taskExecutions, - workerData - }) - }), - Benchmark.add('Dynamic:ClusterPool:FairShare', async () => { - await runTest(dynamicClusterPoolFairShare, { - taskExecutions, - workerData - }) - }), - Benchmark.cycle(), - Benchmark.complete(), - Benchmark.save({ + ...addPools(pools), + cycle(), + complete(), + save({ file: resultsFile, folder: resultsFolder, format: 'json', details: true }), - Benchmark.save({ + save({ file: resultsFile, folder: resultsFolder, format: 'chart.html', details: true }), - Benchmark.save({ + save({ file: resultsFile, folder: resultsFolder, format: 'table.html', diff --git a/src/pools/worker.ts b/src/pools/worker.ts index f1c29b36..2da91457 100644 --- a/src/pools/worker.ts +++ b/src/pools/worker.ts @@ -106,8 +106,8 @@ export interface TaskStatistics { * Enumeration of worker types. */ export const WorkerTypes = Object.freeze({ - cluster: 'cluster', - thread: 'thread' + thread: 'thread', + cluster: 'cluster' } as const) /** -- 2.34.1