https://github.com/morglod/sdfclone
World fastest deep clone based on schema
https://github.com/morglod/sdfclone
clone deep deepclone performance
Last synced: 12 months ago
JSON representation
World fastest deep clone based on schema
- Host: GitHub
- URL: https://github.com/morglod/sdfclone
- Owner: Morglod
- Created: 2024-01-17T17:04:52.000Z (about 2 years ago)
- Default Branch: master
- Last Pushed: 2024-01-17T20:01:19.000Z (about 2 years ago)
- Last Synced: 2025-04-03T03:11:12.471Z (about 1 year ago)
- Topics: clone, deep, deepclone, performance
- Language: TypeScript
- Homepage:
- Size: 53.7 KB
- Stars: 20
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
[](https://www.npmjs.com/package/sdfclone)
[](https://gitHub.com/Morglod/sdfclone/)
# sdfclone
World fastest schema based deep clone for js (as for Jan 2024)
Suited for immutable objects with defined structure.
- ⚡️ +-1% slower than optimal manually written code ⚡️
- 12x faster than structuredClone
- no deps
- detect cycles (optional)
- support all JSON types
- support most of JS types
- support custom functions
- variants not supported yet 😬
- tested with `rfdc` tests
## Usage
```js
import { createCloner } from "sdfclone";
// define schema
const objectSchema = {
x: Number,
y: {
z: String,
c: {
bb: Date,
bb2: Function,
},
gg: [{ ff: Number, hh: Number }],
},
};
// create cloner
const cloner = createCloner(objectSchema);
// or with cycle detector; detectCycles=false by default
const cloner = createCloner(objectSchema, { detectCycles: true });
// clone!
const newObject = cloner(object);
```
or less verbose variant:
```js
import { createCloner, createCloneSchemaFrom } from "sdfclone";
let alreadyCreatedObject = { ... };
// extract schema from object
const objectSchema = createCloneSchemaFrom(alreadyCreatedObject);
// create cloner
const cloner = createCloner(objectSchema);
// than clone!
const newObject = cloner(alreadyCreatedObject);
```
## Benchmark
bun 1.0.21 macbook m1
```
naive x 3,789,560 ops/sec ±0.64% (95 runs sampled)
optimal x 7,908,207 ops/sec ±0.75% (94 runs sampled) <----------------------
JSON.parse x 1,257,746 ops/sec ±0.33% (98 runs sampled)
sdfclone x 7,825,037 ops/sec ±0.70% (94 runs sampled) <----------------------
sdfclone detect cycles x 6,582,222 ops/sec ±0.62% (96 runs sampled)
sdfclone with create x 759,116 ops/sec ±0.44% (95 runs sampled)
sdfclone with schema get and create x 535,369 ops/sec ±0.35% (97 runs sampled)
structured clone x 666,819 ops/sec ±0.63% (93 runs sampled)
rfdc x 3,091,196 ops/sec ±0.36% (96 runs sampled)
lodash cloneDeep x 695,643 ops/sec ±0.32% (97 runs sampled)
fastestJsonCopy x 4,042,250 ops/sec ±0.44% (97 runs sampled)
```
node 18.18.0
```
naive x 2,562,532 ops/sec ±0.96% (96 runs sampled)
optimal x 6,024,499 ops/sec ±0.89% (93 runs sampled) <----------------------
JSON.parse x 467,411 ops/sec ±0.44% (98 runs sampled)
sdfclone x 6,173,111 ops/sec ±0.55% (97 runs sampled) <----------------------
sdfclone detect cycles x 4,261,157 ops/sec ±0.85% (95 runs sampled)
sdfclone with create x 663,451 ops/sec ±0.51% (96 runs sampled)
sdfclone with schema get and create x 434,197 ops/sec ±0.89% (100 runs sampled)
structured clone x 470,649 ops/sec ±0.45% (99 runs sampled)
rfdc x 2,220,032 ops/sec ±0.26% (97 runs sampled)
lodash cloneDeep x 516,606 ops/sec ±0.31% (99 runs sampled)
fastestJsonCopy x 2,266,253 ops/sec ±0.54% (98 runs sampled)
```
## Schema description
```js
// array
[ itemSchema ]
// object
{ field: fieldSchema }
// JSON values
null | Number | String | Boolean
// JS values
undefined | Number | String | Boolean | Function | Symbol | BigInt | Date
// buffers & typed arrays
Buffer | ArrayBuffer | any TypedArrays
// specific JS
Map | Set // this uses JSON.parse(JSON.stringify) technique by default
// use `new ClonerMap(valueSchema)` or `new ClonerSet(valueSchema)` when possible
// for arguments or iterators
// use `new ClonerArrayLike(itemSchema)`
```
Its also possible to pass custom cloner function with:
`new ClonerCustomFn(customCloner: x => x)`
## Utils
Create schema from existing object:
```js
const obj = { ... };
// create schema
const objSchema = createCloneSchemaFrom(obj);
// with option that will also walk inside prototypes cloneProto=false by default
const objSchemaWithProto = createCloneSchemaFrom(obj, { cloneProto: true });
const cloner = createCloner(objSchema);
const newObject = cloner(obj);
```