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",