diff --git a/README.md b/README.md index acaa87f..332a403 100644 --- a/README.md +++ b/README.md @@ -989,46 +989,55 @@ concurrently. ## Benchmark +macOS Big Sur +Version 11.7.9 + +MacBook Pro (15-inch, 2018) +Processor 2.2 GHz 6-Core Intel Core i7 +Memory 16 GB 2400 MHz DDR4 +Graphics Radeon Pro 555X 4 GB +Intel UHD Graphics 630 1536 MB + [//]: # (No deletion!!! Start of Replace Section)
-
avl-tree
-
test nametime taken (ms)executions per secsample deviation
10,000 add randomly125.607.960.00
10,000 add & delete randomly181.225.520.00
10,000 addMany134.127.460.01
10,000 get55.0818.160.01
-
-
binary-tree-overall
-
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add6.17161.950.00
10,000 RBTree add & delete randomly16.0762.222.62e-4
10,000 RBTree get19.8650.362.44e-4
10,000 AVLTree add134.387.440.02
10,000 AVLTree add & delete randomly207.204.830.06
10,000 AVLTree get0.981015.542.73e-5
+
heap
+
test nametime taken (ms)executions per secsample deviation
100,000 add6.51153.594.60e-4
100,000 add & poll31.5931.658.52e-4
rb-tree
-
test nametime taken (ms)executions per secsample deviation
100,000 add86.6511.540.02
100,000 add & delete randomly221.024.520.03
100,000 getNode190.545.250.00
100,000 add & iterator122.108.190.01
-
-
directed-graph
-
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.118896.512.63e-5
1,000 addEdge6.53153.210.00
1,000 getVertex0.052.08e+41.06e-5
1,000 getEdge27.5336.330.01
tarjan224.534.450.01
topologicalSort184.025.430.00
-
-
hash-map
-
test nametime taken (ms)executions per secsample deviation
1,000,000 set126.277.920.05
Native Map 1,000,000 set229.804.350.03
Native Set 1,000,000 add175.835.690.01
1,000,000 set & get121.348.240.03
Native Map 1,000,000 set & get290.803.440.03
Native Set 1,000,000 add & has180.715.530.01
1,000,000 ObjKey set & get357.682.800.07
Native Map 1,000,000 ObjKey set & get310.573.220.06
Native Set 1,000,000 ObjKey add & has278.423.590.05
-
-
heap
-
test nametime taken (ms)executions per secsample deviation
100,000 add & poll24.8540.240.00
100,000 add & dfs33.1430.170.00
10,000 fib add & pop366.112.730.00
-
-
doubly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push217.984.590.07
1,000,000 unshift223.204.480.08
1,000,000 unshift & shift172.875.780.03
1,000,000 addBefore387.132.580.20
-
-
singly-linked-list
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift225.134.440.07
10,000 push & pop234.544.260.02
10,000 addBefore252.623.960.00
-
-
priority-queue
-
test nametime taken (ms)executions per secsample deviation
100,000 add & poll76.4913.070.00
-
-
deque
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push13.2075.752.79e-4
1,000,000 push & pop22.2145.033.27e-4
100,000 push & shift2.26442.241.43e-4
Native Array 100,000 push & shift2329.510.430.10
100,000 unshift & shift2.16463.838.20e-5
Native Array 100,000 unshift & shift4590.640.220.33
+
test nametime taken (ms)executions per secsample deviation
100,000 add85.0811.750.00
100,000 add & delete randomly217.114.610.02
100,000 getNode178.005.620.00
100,000 add & iterator116.318.600.00
queue
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push49.9220.030.02
100,000 push & shift5.07197.285.86e-4
Native Array 100,000 push & shift2315.780.430.13
Native Array 100,000 push & pop4.37228.721.32e-4
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push45.9821.750.01
100,000 push & shift4.91203.497.39e-4
Native JS Array 100,000 push & shift2321.550.430.20
-
stack
-
test nametime taken (ms)executions per secsample deviation
1,000,000 push44.5022.470.01
1,000,000 push & pop53.5718.670.02
+
deque
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push24.8540.240.00
1,000,000 push & pop31.5031.750.00
1,000,000 push & shift30.9332.330.00
100,000 push & shift3.28304.692.35e-4
Native JS Array 100,000 push & shift2040.480.490.08
100,000 unshift & shift2.97336.205.34e-4
Native JS Array 100,000 unshift & shift4113.190.240.25
+
+
hash-map
+
test nametime taken (ms)executions per secsample deviation
1,000,000 set118.598.430.03
Native JS Map 1,000,000 set208.834.790.02
Native JS Set 1,000,000 add168.455.940.01
1,000,000 set & get120.868.270.02
Native JS Map 1,000,000 set & get270.833.690.02
Native JS Set 1,000,000 add & has168.795.920.01
1,000,000 ObjKey set & get335.672.980.05
Native JS Map 1,000,000 ObjKey set & get302.023.310.04
Native JS Set 1,000,000 ObjKey add & has270.813.690.04
trie
-
test nametime taken (ms)executions per secsample deviation
100,000 push42.9523.286.68e-4
100,000 getWords92.1110.860.01
+
test nametime taken (ms)executions per secsample deviation
100,000 push44.8622.299.69e-4
100,000 getWords85.6311.680.01
+
+
avl-tree
+
test nametime taken (ms)executions per secsample deviation
10,000 add randomly128.117.810.00
10,000 get52.8718.916.02e-4
10,000 add & delete randomly189.765.270.00
10,000 addMany136.547.329.74e-4
+
+
binary-tree-overall
+
test nametime taken (ms)executions per secsample deviation
10,000 RBTree add7.00142.819.38e-5
10,000 RBTree add & delete randomly16.8559.341.65e-4
10,000 RBTree get18.2054.931.45e-4
10,000 AVLTree add127.567.840.00
10,000 AVLTree get53.3818.737.89e-4
10,000 AVLTree add & delete randomly190.115.260.00
+
+
directed-graph
+
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.109828.432.34e-6
1,000 addEdge6.14162.811.71e-4
1,000 getVertex0.052.17e+44.30e-7
1,000 getEdge23.0243.440.00
tarjan202.414.940.01
topologicalSort180.325.550.00
+
+
doubly-linked-list
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push209.364.780.04
1,000,000 unshift217.024.610.08
1,000,000 unshift & shift174.285.740.05
1,000,000 addBefore331.233.020.08
+
+
singly-linked-list
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift217.344.600.07
10,000 push & pop216.544.620.01
10,000 addBefore247.694.040.01
+
+
priority-queue
+
test nametime taken (ms)executions per secsample deviation
100,000 add27.8235.940.00
100,000 add & poll78.7612.700.02
+
+
stack
+
test nametime taken (ms)executions per secsample deviation
1,000,000 push40.7524.540.01
1,000,000 push & pop48.0720.800.01
[//]: # (No deletion!!! End of Replace Section) diff --git a/src/data-structures/base/iterable-base.ts b/src/data-structures/base/iterable-base.ts index fbfff56..bda732f 100644 --- a/src/data-structures/base/iterable-base.ts +++ b/src/data-structures/base/iterable-base.ts @@ -6,6 +6,8 @@ export abstract class IterableEntryBase { * Space Complexity: O(1) */ + abstract get size(): number; + /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -125,6 +127,11 @@ export abstract class IterableEntryBase { return false; } + /** + * Time Complexity: O(n) + * Space Complexity: O(1) + */ + /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -248,11 +255,6 @@ export abstract class IterableEntryBase { return; } - /** - * Time Complexity: O(n) - * Space Complexity: O(1) - */ - /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -301,6 +303,8 @@ export abstract class IterableEntryBase { } export abstract class IterableElementBase { + abstract get size(): number; + /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -362,6 +366,11 @@ export abstract class IterableElementBase { return true; } + /** + * Time Complexity: O(n) + * Space Complexity: O(1) + */ + /** * Time Complexity: O(n) * Space Complexity: O(1) @@ -445,11 +454,6 @@ export abstract class IterableElementBase { return; } - /** - * Time Complexity: O(n) - * Space Complexity: O(1) - */ - /** * Time Complexity: O(n) * Space Complexity: O(1) diff --git a/src/data-structures/graph/abstract-graph.ts b/src/data-structures/graph/abstract-graph.ts index dd55500..542ce08 100644 --- a/src/data-structures/graph/abstract-graph.ts +++ b/src/data-structures/graph/abstract-graph.ts @@ -82,6 +82,10 @@ export abstract class AbstractGraph< this._vertexMap = v; } + get size(): number { + return this._vertexMap.size; + } + /** * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it. * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden. diff --git a/src/data-structures/heap/heap.ts b/src/data-structures/heap/heap.ts index 625cef1..bf098b1 100644 --- a/src/data-structures/heap/heap.ts +++ b/src/data-structures/heap/heap.ts @@ -200,7 +200,7 @@ export class Heap extends IterableElementBase { * @param element - the element to check. * @returns Returns true if the specified element is contained; otherwise, returns false. */ - has(element: E): boolean { + override has(element: E): boolean { return this.elements.includes(element); } diff --git a/test/performance/data-structures/binary-tree/avl-tree.test.ts b/test/performance/data-structures/binary-tree/avl-tree.test.ts index 21c2608..5a928b2 100644 --- a/test/performance/data-structures/binary-tree/avl-tree.test.ts +++ b/test/performance/data-structures/binary-tree/avl-tree.test.ts @@ -12,6 +12,9 @@ suite avl.clear(); for (let i = 0; i < arr.length; i++) avl.add(arr[i]); }) + .add(`${TEN_THOUSAND.toLocaleString()} get`, () => { + for (let i = 0; i < arr.length; i++) avl.get(arr[i]); + }) .add(`${TEN_THOUSAND.toLocaleString()} add & delete randomly`, () => { avl.clear(); for (let i = 0; i < arr.length; i++) avl.add(arr[i]); @@ -20,9 +23,6 @@ suite .add(`${TEN_THOUSAND.toLocaleString()} addMany`, () => { avl.clear(); avl.addMany(arr); - }) - .add(`${TEN_THOUSAND.toLocaleString()} get`, () => { - for (let i = 0; i < arr.length; i++) avl.get(arr[i]); }); export { suite }; diff --git a/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts b/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts index 36d89c2..97550f4 100644 --- a/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +++ b/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts @@ -25,13 +25,13 @@ suite avlTree.clear(); for (let i = 0; i < arr.length; i++) avlTree.add(arr[i]); }) + .add(`${TEN_THOUSAND.toLocaleString()} AVLTree get`, () => { + for (let i = 0; i < arr.length; i++) avlTree.get(arr[i]); + }) .add(`${TEN_THOUSAND.toLocaleString()} AVLTree add & delete randomly`, () => { avlTree.clear(); for (let i = 0; i < arr.length; i++) avlTree.add(arr[i]); for (let i = 0; i < arr.length; i++) avlTree.delete(arr[i]); - }) - .add(`${TEN_THOUSAND.toLocaleString()} AVLTree get`, () => { - for (let i = 0; i < arr.length; i++) avlTree.get(arr[i]); }); export { suite }; diff --git a/test/performance/data-structures/hash/hash-map.test.ts b/test/performance/data-structures/hash/hash-map.test.ts index c37c3d2..f9112a8 100644 --- a/test/performance/data-structures/hash/hash-map.test.ts +++ b/test/performance/data-structures/hash/hash-map.test.ts @@ -21,13 +21,13 @@ if (isCompetitor) { }); } -suite.add(`Native Map ${MILLION.toLocaleString()} set`, () => { +suite.add(`Native JS Map ${MILLION.toLocaleString()} set`, () => { const hm = new Map(); for (let i = 0; i < MILLION; i++) hm.set(i, i); }); -suite.add(`Native Set ${MILLION.toLocaleString()} add`, () => { +suite.add(`Native JS Set ${MILLION.toLocaleString()} add`, () => { const hs = new Set(); for (let i = 0; i < MILLION; i++) hs.add(i); @@ -49,14 +49,14 @@ if (isCompetitor) { }); } -suite.add(`Native Map ${MILLION.toLocaleString()} set & get`, () => { +suite.add(`Native JS Map ${MILLION.toLocaleString()} set & get`, () => { const hm = new Map(); for (let i = 0; i < MILLION; i++) hm.set(i, i); for (let i = 0; i < MILLION; i++) hm.get(i); }); -suite.add(`Native Set ${MILLION.toLocaleString()} add & has`, () => { +suite.add(`Native JS Set ${MILLION.toLocaleString()} add & has`, () => { const hs = new Set(); for (let i = 0; i < MILLION; i++) hs.add(i); @@ -74,7 +74,7 @@ suite.add(`${MILLION.toLocaleString()} ObjKey set & get`, () => { for (let i = 0; i < MILLION; i++) hm.get(objKeys[i]); }); -suite.add(`Native Map ${MILLION.toLocaleString()} ObjKey set & get`, () => { +suite.add(`Native JS Map ${MILLION.toLocaleString()} ObjKey set & get`, () => { const hm = new Map<[number, number], number>(); const objs: [number, number][] = []; for (let i = 0; i < MILLION; i++) { @@ -85,7 +85,7 @@ suite.add(`Native Map ${MILLION.toLocaleString()} ObjKey set & get`, () => { for (let i = 0; i < MILLION; i++) hm.get(objs[i]); }); -suite.add(`Native Set ${MILLION.toLocaleString()} ObjKey add & has`, () => { +suite.add(`Native JS Set ${MILLION.toLocaleString()} ObjKey add & has`, () => { const hs = new Set<[number, number]>(); const objs: [number, number][] = []; for (let i = 0; i < MILLION; i++) { diff --git a/test/performance/data-structures/heap/heap.test.ts b/test/performance/data-structures/heap/heap.test.ts index ef0632b..61a3c88 100644 --- a/test/performance/data-structures/heap/heap.test.ts +++ b/test/performance/data-structures/heap/heap.test.ts @@ -1,26 +1,26 @@ -import { FibonacciHeap, Heap } from '../../../../src'; +import { Heap } from '../../../../src'; import * as Benchmark from 'benchmark'; -import { magnitude } from '../../../utils'; +import { getRandomInt, magnitude } from '../../../utils'; const suite = new Benchmark.Suite(); -const { HUNDRED_THOUSAND, TEN_THOUSAND } = magnitude; +const { HUNDRED_THOUSAND } = magnitude; +const indicesHT = new Array(HUNDRED_THOUSAND).fill(0).map(() => getRandomInt(0, HUNDRED_THOUSAND - 1)); suite + .add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => { + const heap = new Heap([], { comparator: (a, b) => b - a }); + for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(indicesHT[i]); + }) .add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => { const heap = new Heap([], { comparator: (a, b) => b - a }); - for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i); + for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(indicesHT[i]); for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.poll(); - }) - .add(`${HUNDRED_THOUSAND.toLocaleString()} add & dfs`, () => { - const heap = new Heap([], { comparator: (a, b) => b - a }); - for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i); - heap.dfs(); - }) - .add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => { - const fbHeap = new FibonacciHeap(); - for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.push(i); - for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.pop(); }); +// .add(`${TEN_THOUSAND.toLocaleString()} fib add & pop`, () => { +// const fbHeap = new FibonacciHeap(); +// for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.push(i); +// for (let i = 1; i <= TEN_THOUSAND; i++) fbHeap.pop(); +// }); export { suite }; diff --git a/test/performance/data-structures/priority-queue/priority-queue.test.ts b/test/performance/data-structures/priority-queue/priority-queue.test.ts index bfcd760..ab0490d 100644 --- a/test/performance/data-structures/priority-queue/priority-queue.test.ts +++ b/test/performance/data-structures/priority-queue/priority-queue.test.ts @@ -1,5 +1,5 @@ -import { PriorityQueue as CPriorityQueue } from 'js-sdsl'; import { PriorityQueue } from '../../../../src'; +import { PriorityQueue as CPriorityQueue } from 'js-sdsl'; import * as Benchmark from 'benchmark'; import { magnitude } from '../../../utils'; import { isCompetitor } from '../../../config'; @@ -7,12 +7,17 @@ import { isCompetitor } from '../../../config'; const suite = new Benchmark.Suite(); const { HUNDRED_THOUSAND } = magnitude; -suite.add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => { - const pq = new PriorityQueue([], { comparator: (a, b) => b - a }); +suite + .add(`${HUNDRED_THOUSAND.toLocaleString()} add`, () => { + const heap = new PriorityQueue([], { comparator: (a, b) => b - a }); + for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i); + }) + .add(`${HUNDRED_THOUSAND.toLocaleString()} add & poll`, () => { + const heap = new PriorityQueue([], { comparator: (a, b) => b - a }); - for (let i = 0; i < HUNDRED_THOUSAND; i++) pq.add(i); - for (let i = 0; i < HUNDRED_THOUSAND; i++) pq.poll(); -}); + for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.add(i); + for (let i = 0; i < HUNDRED_THOUSAND; i++) heap.poll(); + }); if (isCompetitor) { suite.add(`CPT ${HUNDRED_THOUSAND.toLocaleString()} add & pop`, () => { const pq = new CPriorityQueue(); diff --git a/test/performance/data-structures/queue/deque.test.ts b/test/performance/data-structures/queue/deque.test.ts index a7ec4f3..e953aea 100644 --- a/test/performance/data-structures/queue/deque.test.ts +++ b/test/performance/data-structures/queue/deque.test.ts @@ -21,25 +21,25 @@ if (isCompetitor) { } suite - // .add(`${TEN_THOUSAND.toLocaleString()} push & delete`, () => { - // const deque = new Deque(); - // - // for (let i = 0; i < TEN_THOUSAND; i++) deque.push(i); - // for (let i = 0; i < TEN_THOUSAND; i++) deque.delete(randomIndicesTenThousand[i]); - // }) .add(`${MILLION.toLocaleString()} push & pop`, () => { const deque = new Deque(); for (let i = 0; i < MILLION; i++) deque.push(i); for (let i = 0; i < MILLION; i++) deque.pop(); }) + .add(`${MILLION.toLocaleString()} push & shift`, () => { + const deque = new Deque(); + + for (let i = 0; i < MILLION; i++) deque.push(i); + for (let i = 0; i < MILLION; i++) deque.shift(); + }) .add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { const deque = new Deque(); for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.push(i); for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.shift(); }) - .add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { + .add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { const array = new Array(); for (let i = 0; i < HUNDRED_THOUSAND; i++) array.push(i); @@ -51,7 +51,7 @@ suite for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.unshift(i); for (let i = 0; i < HUNDRED_THOUSAND; i++) deque.shift(); }) - .add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} unshift & shift`, () => { + .add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} unshift & shift`, () => { const array = new Array(); for (let i = 0; i < HUNDRED_THOUSAND; i++) array.unshift(i); diff --git a/test/performance/data-structures/queue/queue.test.ts b/test/performance/data-structures/queue/queue.test.ts index 2347087..d2b34dc 100644 --- a/test/performance/data-structures/queue/queue.test.ts +++ b/test/performance/data-structures/queue/queue.test.ts @@ -25,18 +25,11 @@ suite.add(`${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { for (let i = 0; i < HUNDRED_THOUSAND; i++) queue.push(i); for (let i = 0; i < HUNDRED_THOUSAND; i++) queue.shift(); }); -suite - .add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { - const arr = new Array(); +suite.add(`Native JS Array ${HUNDRED_THOUSAND.toLocaleString()} push & shift`, () => { + const arr = new Array(); - for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.push(i); - for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.shift(); - }) - .add(`Native Array ${HUNDRED_THOUSAND.toLocaleString()} push & pop`, () => { - const arr = new Array(); - - for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.push(i); - for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.pop(); - }); + for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.push(i); + for (let i = 0; i < HUNDRED_THOUSAND; i++) arr.shift(); +}); export { suite }; diff --git a/test/performance/reportor.ts b/test/performance/reportor.ts index e53c7fe..9e765a5 100644 --- a/test/performance/reportor.ts +++ b/test/performance/reportor.ts @@ -4,6 +4,7 @@ import * as fs from 'fs'; import * as fastGlob from 'fast-glob'; import { Color, numberFix, render } from '../utils'; import { PerformanceTest } from './types'; +import * as console from 'console'; const args = process.argv.slice(2); @@ -171,7 +172,48 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText: }); } -performanceTests.forEach(item => { +const order = [ + 'heap', + 'rb-tree', + 'queue', + 'deque', + 'hash-map', + 'trie', + 'avl-tree', + 'binary-tree-overall', + 'directed-graph', + 'doubly-linked-list', + 'singly-linked-list', + 'priority-queue', + 'stack' +]; + +const sortedPerformanceTests = [...performanceTests].sort((a, b) => { + const indexA = order.indexOf(a.testName); + const indexB = order.indexOf(b.testName); + + // If both a and b are in the order, sort them according to their indices in the order. + if (indexA !== -1 && indexB !== -1) { + return indexA - indexB; + } + + // If there is only 'a' in the order, then place 'b' in front. + if (indexA !== -1) { + return 1; + } + + // If only b is in the order, then a should be placed before it. + if (indexB !== -1) { + return -1; + } + + // If neither a nor b are in order, keep their original order + return 0; +}); + +console.log(`${GREEN} Found tests${END}: ${sortedPerformanceTests.map(test => test.testName)}`); + +sortedPerformanceTests.forEach(item => { const { suite, testName, file } = item; console.log(coloredLabeled('Running', file));