limu 🍋
limu
— это сокращение от love immutable, созданное для эффективного создания и работы с неизменяемыми объектами.
Он быстр, почти в 2 или 20 раз быстрее, чем immer
в различных ситуациях.
Нажмите на эту онлайн-демонстрацию, чтобы посмотреть удивительный результат.
Посмотрите другие результаты тестирования
1. git clone git@github.com:tnfe/limu.git
2. cd benchmark
3. npm i
4. node ./limu-vs-immer.js
Почему появился Limu? Поскольку я планирую выпустить concent V3 в следующем году, мне нужен более быстрый инструмент для работы с неизменяемыми данными JS, поэтому родился Limu.
Производительность ⚡️
Он почти в 2 или 20 раз быстрее, чем immer
в различных ситуациях.
Простая демонстрация
Выполните команду cd benchmark
и node ./readme-demo.js
bash.
Выполните приведенный ниже код:
const immer = require('immer');
const limu = require('limu');
immer.setAutoFreeze(false);
limu.setAutoFreeze(false);
function getBase() {
const base = {
a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a1: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a2: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a3: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a4: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a5: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a6: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a7: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a8: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a9: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a10: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a11: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
a12: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 1 } } } } } } } } } } } } },
arr: [1, 2, 3],
b: null,
};
return base;
};
function die(label) {
throw new Error(label);
};
function oneBenchmark(lib, base) {
const start = Date.now();
const draft = lib.createDraft(base);
draft.a.b.c.d.e.f.g = 999;
draft.arr[1] = 100;
const final = lib.finishDraft(draft);
if (final === base) {
die('should not be equal');
}
if (final.arr[1] !== 100) {
die('final.arr[1] !== 100');
}
if (base.arr[1] !== 2) {
die('base.arr[1] !== 1');
}
const draft2 = lib.createDraft(base);
delete draft2.b;
const final2 = lib.finishDraft(draft2);
if (final2 === base) {
die('should not be equal');
}
if (base.b !== null) {
die('base.b should be null');
}
const taskSpend = Date.now() - start;
return taskSpend;
}
function measureBenchmark(label, loopLimit) {
const immutLibs = { limu, immer };
const lib = immutLibs[label];
console.log(` ------------- ${label} benchmark ------------- `);
const base = getBase();
let totalSpend = 0;
for (let i = 0; i < loopLimit; i++) {
totalSpend += oneBenchmark(lib, base);
}
console.log(`${label} avg spend ${totalSpend / loopLimit} ms n`);
}
measureBenchmark('limu', 10000);
measureBenchmark('immer', 10000);
на MacBook 2021 m1 max
, результат перфекта таков:
------------- limu benchmark -------------
limu avg spend 0.0066 ms
------------- immer benchmark -------------
immer avg spend 0.0446 ms
Как видите, limu почти в семь раз быстрее, чем immer в вышеупомянутом случае.
Сложная демонстрация
Выполните следующие шаги, чтобы провести более сложный перф-тест
1. cd benchmark
2. npm i
3. node ./limu-vs-immer.js
Вы можете изменить параметры hasArr
、lessDeepOp
для тестирования производительности в различных ситуациях
// // ************************************************************************
const curStrategy = process.env.ST || strategyConsts.BASE_F_AUTO_F;
// change params 'hasArr'、'lessDeepOp' to test limu and immer performance in different situations
// then run npm cmd: `npm run s1`、`npm run s2`、`npm run s3`、`npm run s4` to see perf result
const hasArr = false; // operate arr or not
const lessDeepOp = true; // has more deep operation or not
// ************************************************************************
Результат тестирования на macbook 2021 max pro:
-----------------------[ hasArr true, lessOp true ]-------------------
(reuseBase: true, autoFreeze: true) immer 2.797 ms : limu 1.287 ms
(reuseBase: false, autoFreeze: true) immer 2.835 ms : limu 1.313 ms
(reuseBase: true, autoFreeze: false) immer 2.049 ms : limu 0.089 ms
(reuseBase: false, autoFreeze: false) immer 2.096 ms : limu 0.146 ms
-----------------------[ hasArr true, lessOp false ]------------------
(reuseBase: true, autoFreeze: true) immer 2.946 ms : limu 1.268 ms
(reuseBase: false, autoFreeze: true) immer 3.005 ms : limu 1.345 ms
(reuseBase: true, autoFreeze: false) immer 2.162 ms : limu 0.147 ms
(reuseBase: false, autoFreeze: false) immer 2.169 ms : limu 0.161 ms
-----------------------[ hasArr false, lessOp true ]--------------------------
(reuseBase: true, autoFreeze: true) immer 2.253 ms : limu 0.659 ms
(reuseBase: false, autoFreeze: true) immer 2.261 ms : limu 0.705 ms
(reuseBase: true, autoFreeze: false) immer 1.386 ms : limu 0.015 ms
(reuseBase: false, autoFreeze: false) immer 1.469 ms : limu 0.017 ms
-----------------------[ hasArr false, lessOp false ]--------------------------
(reuseBase: true, autoFreeze: true) immer 2.266 ms : limu 0.604 ms
(reuseBase: false, autoFreeze: true) immer 2.201 ms : limu 0.643 ms
(reuseBase: true, autoFreeze: false) immer 1.565 ms : limu 0.055 ms
(reuseBase: false, autoFreeze: false) immer 1.479 ms : limu 0.061 ms
Отправьте свой тест
Вы можете отправить свой тест в каталог бенчмарков в git-репо limu