diff --git a/CHANGELOG.md b/CHANGELOG.md index e5dd9e8..8bf041d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### 2.5.0 +* [#108: Add destructuring profile.](https://github.com/haensl/js-profiler/issues/108) + ### 2.4.2 * [#106: Add options to JSON result.](https://github.com/haensl/js-profiler/issues/106) * Update dependencies. diff --git a/README.md b/README.md index c212720..79b865f 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ JS-Profiler powers [https://js-profiler.com](https://js-profiler.com). * [array concatenation](#array-concat) * [array copying](#array-copy) * [comparison operators](#comparison-operators) + * [(de-)composition](#composition) * [guards](#guards) * [loops](#loops) * [map access](#map:access) @@ -45,6 +46,8 @@ JS-Profiler powers [https://js-profiler.com](https://js-profiler.com). ## Updates +### [v2.5.0](https://github.com/haensl/js-profiler/releases/tag/v2.5.0): New profile: [(de-)composition.](#composition) + ### [v2.3.0](https://github.com/haensl/js-profiler/releases/tag/v2.3.0): A new contributor and a new profile: [shallow array copying.](#array-copy) We are happy to welcome [Josh Howe](https://github.com/joshtch) as a contributor to JS-Profiler! He added a [new profile comparing ways to shallow copy arrays](#array-copy). @@ -246,6 +249,22 @@ Profiled operations: * `b = new Array(); for(...){ b.push(a[i]) }` * `b = new Array(a.length); for(...){ b[i] = a[i] }` +### [(de-)composition](https://js-profiler.com/#de-composition) +(De-)Composition: composing objects, arrays and variables from each other. + +Profiled operations: + * `const { a, b } = obj` + * `const { a = i } = obj` + * `const [a, b] = arr` + * `const [a = i, b] = d` + * `const [a, b, ...tail] = d` + * `const a = arr[i]` + * `const a = arr[i] || j` + * `const a = obj.b` + * `const a = obj.b || i` + * `const [a, b] = [b, a]` + * `const c = b; b = a; a = c` + ### [comarison operators](https://js-profiler.com/#comparison-operators) Variable comparison operators. diff --git a/docs/js-profiler.1 b/docs/js-profiler.1 index 540744a..c073ba5 100644 --- a/docs/js-profiler.1 +++ b/docs/js-profiler.1 @@ -1,5 +1,5 @@ ." vim: set syn=nroff -.TH js-profiler 1 "February 2021" "js-profiler v2.4.2" +.TH js-profiler 1 "June 2021" "js-profiler v2.5.0" .SH NAME js-profiler - A JavaScript profiling tool and collection of profiling modules and benchmarks. diff --git a/lib/profiles/array-copy/index.js b/lib/profiles/array-copy/index.js index 0060ca3..ea723bb 100644 --- a/lib/profiles/array-copy/index.js +++ b/lib/profiles/array-copy/index.js @@ -5,6 +5,7 @@ const copySlice = { codeSample: 'a.slice()', keywords: [ 'array', + 'clone', 'copy', 'slice', 'method' @@ -16,9 +17,10 @@ const copySpread = { description: 'copy using Array spread syntax', keywords: [ 'array', + 'clone', 'copy', 'spread', - 'syntax', + 'syntax' ].sort(), codeSample: '[...a]', f: (d) => [...d[0]] @@ -28,6 +30,7 @@ const copyFrom = { description: 'copy using Array.from()', keywords: [ 'array', + 'clone', 'copy', 'from', 'method' @@ -40,6 +43,7 @@ const copyNewArray = { description: 'spread into Array constructor', keywords: [ 'array', + 'clone', 'copy', 'new', 'constructor' @@ -52,6 +56,7 @@ const copyConcatAB = { description: 'concatenate empty Array literal', keywords: [ 'array', + 'clone', 'copy', 'concat', 'method' @@ -64,6 +69,7 @@ const copyConcatBA = { description: 'concatenate onto empty Array literal', keywords: [ 'array', + 'clone', 'copy', 'concat', 'method' @@ -77,6 +83,7 @@ const copyPrependLiteral = { codeSample: 'b = []; Array.prototype.unshift.apply(b, a)', keywords: [ 'array', + 'clone', 'copy', 'literal', 'apply', @@ -95,6 +102,7 @@ const copyPrependPreallocate = { description: 'prepend to constructed Array', keywords: [ 'array', + 'clone', 'copy', 'preallocate', 'apply', @@ -116,6 +124,7 @@ const copyAppendLiteral = { description: 'append to Array literal using spread', keywords: [ 'array', + 'clone', 'copy', 'literal', 'apply', @@ -136,6 +145,7 @@ const copyAppendSpreadPreallocate = { description: 'append to constructed Array using spread', keywords: [ 'array', + 'clone', 'copy', 'preallocate', 'constructor', @@ -157,6 +167,7 @@ const copyAppendForPreallocate = { description: 'append to constructed Array in a for loop', keywords: [ 'array', + 'clone', 'copy', 'preallocate', 'constructor', @@ -182,6 +193,7 @@ const copyAppendForLiteral = { description: 'append to Array literal in a for loop', keywords: [ 'array', + 'clone', 'copy', 'push', 'for', @@ -207,6 +219,7 @@ const copySetForPreallocate = { description: 'preallocate new Array and assign values in a for loop', keywords: [ 'array', + 'clone', 'copy', 'preallocate', 'set', @@ -248,8 +261,8 @@ const functions = [ module.exports = { name: 'array copying', description: { - long: 'Array copying variations: creating a new array with the same elements as an existing array.', - short: 'Array copying variations.', + long: 'Array copying/cloning variations: creating a new array with the same elements as an existing array.', + short: 'Array copying/cloning variations.' }, keywords: unique( functions.map((fn) => fn.keywords) diff --git a/lib/profiles/composition/index.js b/lib/profiles/composition/index.js new file mode 100644 index 0000000..991f41c --- /dev/null +++ b/lib/profiles/composition/index.js @@ -0,0 +1,220 @@ +/* eslint-disable no-unused-vars */ +const { unique } = require('../../support/array'); + +const destructureObject = { + description: 'Destructuring an Object', + codeSample: 'const { a, b } = obj', + keywords: [ + 'assignment', + 'object', + 'destructuring', + 'decomposition', + 'composition' + ].sort(), + f: (d) => { + const { num, obj } = d; + }, + testDataType: 'object' +}; + +const destructureObjectDefault = { + description: 'Destructuring an Object with default values', + codeSample: 'const { a = i } = obj', + keywords: [ + 'assignment', + 'object', + 'destructuring', + 'decomposition', + 'composition', + 'default', + 'values' + ].sort(), + f: (d) => { + const { num = 5, foo = 'bar' } = d; + }, + testDataType: 'object' +}; + +const destructureArray = { + description: 'Destructuring an Array', + codeSample: 'const [a,b] = arr', + keywords: [ + 'assignment', + 'array', + 'destructuring', + 'decomposition', + 'composition' + ].sort(), + f: (d) => { + const [a, b] = d; + }, + testDataType: 'array' +}; + +const destructureArrayDefault = { + description: 'Destructuring an Array with default values', + codeSample: 'const [a = i, b] = arr', + keywords: [ + 'assignment', + 'array', + 'destructuring', + 'decomposition', + 'composition', + 'default', + 'values' + ].sort(), + f: (d) => { + const [a = 5, b] = d; + }, + testDataType: 'array' +}; + +const destructureArrayTail = { + description: 'Destructuring an Array with tail', + codeSample: 'const [a,b, ...tail] = arr', + keywords: [ + 'assignment', + 'array', + 'destructuring', + 'decomposition', + 'composition', + 'rest', + 'tail' + ].sort(), + f: (d) => { + const [a, b, ...tail] = d; + }, + testDataType: 'array' +}; + +const assignArray = { + description: 'Assignment from array items', + codeSample: 'const a = arr[i]', + keywords: [ + 'array', + 'assignment', + 'decomposition', + 'composition' + ].sort(), + f: (d) => { + const a = d[0]; + const b = d[1]; + }, + testDataType: 'array' +}; + +const assignArrayDefault = { + description: 'Assignment from array items with default', + codeSample: 'const a = arr[i] || j', + keywords: [ + 'array', + 'assignment', + 'decomposition', + 'composition', + 'default', + 'values' + ].sort(), + f: (d) => { + const a = d[0] || 5; + const b = d[1]; + }, + testDataType: 'array' +}; + +const assignObject = { + description: 'Assignment from object properties', + codeSample: 'const a = obj.b', + keywords: [ + 'object', + 'assignment', + 'decomposition', + 'composition' + ].sort(), + f: (d) => { + const str = d.obj.str; + }, + testDataType: 'object' +}; + +const assignObjectDefault = { + description: 'Assignment from object properties with default', + codeSample: 'const a = obj.b || i', + keywords: [ + 'object', + 'assignment', + 'decomposition', + 'composition', + 'default', + 'values' + ].sort(), + f: (d) => { + const str = d.obj.foo || 'bar'; + }, + testDataType: 'object' +}; + +const destructureSwapArray = { + description: 'Swapping variables via Array destructuring', + codeSample: 'const [a, b] = [b, a]', + keywords: [ + 'array', + 'destructuring', + 'swap', + 'variables', + 'composition', + 'decomposition' + ], + f: (d) => { + let a = d[0]; + let b = d[1]; + [a, b] = [b, a]; + }, + testDataType: 'array' +}; + +const assignSwapArray = { + description: 'Swapping variables via assignment', + codeSample: 'const c = b; b = a; a = c;', + keywords: [ + 'swap', + 'variables', + 'composition', + 'decomposition' + ], + f: (d) => { + let a = d[0]; + let b = d[1]; + const c = b; + b = a; + a = c; + }, + testDataType: 'array' +}; + +const functions = [ + destructureArray, + destructureArrayDefault, + destructureArrayTail, + destructureObject, + destructureObjectDefault, + destructureSwapArray, + assignArray, + assignArrayDefault, + assignObject, + assignObjectDefault, + assignSwapArray +]; + +module.exports = { + name: '(de-)composition', + description: { + short: '(De-)composing objects, variables and arrays.', + long: '(De-)composing objects, variables and arrays from each other.' + }, + keywords: unique( + functions.map((fn) => fn.keywords) + .reduce((keywords, fnKeywords) => [...keywords, ...fnKeywords]) + ).sort(), + functions +}; +/* eslint-enable no-unused-vars */ diff --git a/lib/support/testdata/index.js b/lib/support/testdata/index.js index 9887ce5..584a222 100644 --- a/lib/support/testdata/index.js +++ b/lib/support/testdata/index.js @@ -11,13 +11,13 @@ const intArray = (len) => { }; const definedObject = () => ({ - num: 1, - obj: { - str: 'd' - }, - str: 'f', - arr: [], - bool: true + num: 1, + obj: { + str: 'd' + }, + str: 'f', + arr: [], + bool: true }); const objectMap = (len) => { diff --git a/package-lock.json b/package-lock.json index 3266968..6857a01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { "name": "js-profiler", - "version": "2.4.2", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "2.4.2", + "version": "2.5.0", "license": "MIT", "dependencies": { "@haensl/log": "^1.2.2", diff --git a/package.json b/package.json index 23355cc..fab1ef0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "js-profiler", - "version": "2.4.2", + "version": "2.5.0", "description": "Javascript profiling tool and collection of performance profiles for various JavaScript built-ins.", "main": "lib/index.js", "man": "./docs/js-profiler.1.gz",