X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=benchmarks%2Fworker-selection%2Fless.mjs;fp=benchmarks%2Fworker-selection%2Fless.mjs;h=e839107d0978cacb32f6d55521bcc4455e5615f0;hb=8f810074232deefe64634a8942b1db5b8d3bb0dc;hp=0000000000000000000000000000000000000000;hpb=8a97042123ae9a0404637711b8da7c6e7e4424c7;p=poolifier.git diff --git a/benchmarks/worker-selection/less.mjs b/benchmarks/worker-selection/less.mjs new file mode 100644 index 00000000..e839107d --- /dev/null +++ b/benchmarks/worker-selection/less.mjs @@ -0,0 +1,192 @@ +import Benchmark from 'benny' +import { generateRandomInteger } from '../benchmarks-utils.mjs' + +function generateRandomTasksMap ( + numberOfWorkers, + maxNumberOfTasksPerWorker = 10 +) { + const tasksArray = [] + for (let i = 0; i < numberOfWorkers; i++) { + const task = [i, generateRandomInteger(maxNumberOfTasksPerWorker)] + tasksArray.push(task) + } + return new Map(tasksArray) +} + +const tasksMap = generateRandomTasksMap(60, 20) + +function loopSelect (tasksMap) { + let minValue = Infinity + let minKey + for (const [key, value] of tasksMap) { + if (value === 0) { + return key + } else if (value < minValue) { + minKey = key + minValue = value + } + } + return [minKey, minValue] +} + +function arraySortSelect (tasksMap) { + const tasksArray = Array.from(tasksMap) + return tasksArray.sort((a, b) => { + if (a[1] < b[1]) { + return -1 + } else if (a[1] > b[1]) { + return 1 + } + return 0 + })[0] +} + +const defaultComparator = (a, b) => { + return a < b +} + +const defaultPivotIndexSelect = (leftIndex, rightIndex) => { + return leftIndex + Math.floor((rightIndex - leftIndex) / 2) +} + +const randomPivotIndexSelect = (leftIndex, rightIndex) => { + return generateRandomInteger(rightIndex, leftIndex) +} + +function swap (array, index1, index2) { + const tmp = array[index1] + array[index1] = array[index2] + array[index2] = tmp +} + +function partition ( + array, + leftIndex, + rightIndex, + pivotIndex, + compare = defaultComparator +) { + const pivotValue = array[pivotIndex] + swap(array, pivotIndex, rightIndex) + let storeIndex = leftIndex + for (let i = leftIndex; i < rightIndex; i++) { + if (compare(array[i], pivotValue)) { + swap(array, storeIndex, i) + storeIndex++ + } + } + swap(array, rightIndex, storeIndex) + return storeIndex +} + +function selectLoop ( + array, + k, + leftIndex, + rightIndex, + compare = defaultComparator, + pivotIndexSelect = defaultPivotIndexSelect +) { + while (true) { + if (leftIndex === rightIndex) return array[leftIndex] + let pivotIndex = pivotIndexSelect(leftIndex, rightIndex) + pivotIndex = partition(array, leftIndex, rightIndex, pivotIndex, compare) + if (k === pivotIndex) { + return array[k] + } else if (k < pivotIndex) { + rightIndex = pivotIndex - 1 + } else { + leftIndex = pivotIndex + 1 + } + } +} + +function selectRecursion ( + array, + k, + leftIndex, + rightIndex, + compare = defaultComparator, + pivotIndexSelect = defaultPivotIndexSelect +) { + if (leftIndex === rightIndex) return array[leftIndex] + let pivotIndex = pivotIndexSelect(leftIndex, rightIndex) + pivotIndex = partition(array, leftIndex, rightIndex, pivotIndex, compare) + if (k === pivotIndex) { + return array[k] + } else if (k < pivotIndex) { + return selectRecursion(array, k, leftIndex, pivotIndex - 1, compare) + } else { + return selectRecursion(array, k, pivotIndex + 1, rightIndex, k, compare) + } +} + +function quickSelectLoop (tasksMap) { + const tasksArray = Array.from(tasksMap) + + return selectLoop(tasksArray, 0, 0, tasksArray.length - 1, (a, b) => { + return a[1] < b[1] + }) +} + +function quickSelectLoopRandomPivot (tasksMap) { + const tasksArray = Array.from(tasksMap) + + return selectLoop( + tasksArray, + 0, + 0, + tasksArray.length - 1, + (a, b) => { + return a[1] < b[1] + }, + randomPivotIndexSelect + ) +} + +function quickSelectRecursion (tasksMap) { + const tasksArray = Array.from(tasksMap) + + return selectRecursion(tasksArray, 0, 0, tasksArray.length - 1, (a, b) => { + return a[1] < b[1] + }) +} + +function quickSelectRecursionRandomPivot (tasksMap) { + const tasksArray = Array.from(tasksMap) + + return selectRecursion( + tasksArray, + 0, + 0, + tasksArray.length - 1, + (a, b) => { + return a[1] < b[1] + }, + randomPivotIndexSelect + ) +} + +Benchmark.suite( + 'Least used worker tasks distribution', + Benchmark.add('Loop select', () => { + loopSelect(tasksMap) + }), + Benchmark.add('Array sort select', () => { + arraySortSelect(tasksMap) + }), + Benchmark.add('Quick select loop', () => { + quickSelectLoop(tasksMap) + }), + Benchmark.add('Quick select loop with random pivot', () => { + quickSelectLoopRandomPivot(tasksMap) + }), + Benchmark.add('Quick select recursion', () => { + quickSelectRecursion(tasksMap) + }), + Benchmark.add('Quick select recursion with random pivot', () => { + quickSelectRecursionRandomPivot(tasksMap) + }), + Benchmark.cycle(), + Benchmark.complete() +)