diff --git a/.gitignore b/.gitignore index 3c3629e..76efb07 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.vscode diff --git a/package-lock.json b/package-lock.json index a422b37..1772ad4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "piecs": "0.4.0", "tiny-ecs": "2.0.0", "uecs": "0.4.2", - "wolf-ecs": "2.1.1" + "wolf-ecs": "^2.1.3" }, "devDependencies": { "@types/node": "^16.9.1", @@ -140,9 +140,9 @@ "integrity": "sha512-oPwSibOqllZeBu6U2v/wkqIq/XSiwaf0bff1aJhuPEBOqRWuo8iH/RP+bzPPUDdwQ6vRljIkksy0plmEIfbc3w==" }, "node_modules/wolf-ecs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/wolf-ecs/-/wolf-ecs-2.1.1.tgz", - "integrity": "sha512-Wxdvv7hiJQdbRmfv/plm8xSPRyRg4dPkwajVEZf1mjt4ctumLAdZcvc4LIkFCvhLEABrX/KgTgpA5ucUGymahw==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/wolf-ecs/-/wolf-ecs-2.1.3.tgz", + "integrity": "sha512-zTmUsc85VrvFWi7BtZGgF2ZVtcohtMEeSC3fQrWVOENDJkXEm380EFsthr6tFWRJACFLWkw0zUCR6aBFuyTq+A==" } }, "dependencies": { @@ -241,9 +241,9 @@ "integrity": "sha512-oPwSibOqllZeBu6U2v/wkqIq/XSiwaf0bff1aJhuPEBOqRWuo8iH/RP+bzPPUDdwQ6vRljIkksy0plmEIfbc3w==" }, "wolf-ecs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/wolf-ecs/-/wolf-ecs-2.1.1.tgz", - "integrity": "sha512-Wxdvv7hiJQdbRmfv/plm8xSPRyRg4dPkwajVEZf1mjt4ctumLAdZcvc4LIkFCvhLEABrX/KgTgpA5ucUGymahw==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/wolf-ecs/-/wolf-ecs-2.1.3.tgz", + "integrity": "sha512-zTmUsc85VrvFWi7BtZGgF2ZVtcohtMEeSC3fQrWVOENDJkXEm380EFsthr6tFWRJACFLWkw0zUCR6aBFuyTq+A==" } } } diff --git a/package.json b/package.json index fd4e0bc..f4be90c 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "piecs": "0.4.0", "tiny-ecs": "2.0.0", "uecs": "0.4.2", - "wolf-ecs": "2.1.1" + "wolf-ecs": "2.1.3" }, "devDependencies": { "@types/node": "^16.9.1", diff --git a/src/bench.js b/src/bench.js index 6ea28af..34ecf69 100644 --- a/src/bench.js +++ b/src/bench.js @@ -4,18 +4,18 @@ import { fileURLToPath } from "node:url"; import { Worker } from "node:worker_threads"; const LIBRARIES = [ - "becsy", - "bitecs", - "ecsy", - "geotic", - "goodluck", - "harmony-ecs", - "javelin-ecs", - "perform-ecs", - "picoes", - "piecs", - "tiny-ecs", - "uecs", + // "becsy", + // "bitecs", + // "ecsy", + // "geotic", + // "goodluck", + // "harmony-ecs", + // "javelin-ecs", + // "perform-ecs", + // "picoes", + // "piecs", + // "tiny-ecs", + // "uecs", "wolf-ecs", ]; @@ -26,6 +26,7 @@ const BENCHMARKS = { frag_iter: 100, entity_cycle: 1_000, add_remove: 1_000, + query_stress: 100, }; let libraries = []; diff --git a/src/cases/wolf-ecs/add_remove.js b/src/cases/wolf-ecs/add_remove.js index 67ab354..e0eb078 100644 --- a/src/cases/wolf-ecs/add_remove.js +++ b/src/cases/wolf-ecs/add_remove.js @@ -1,15 +1,16 @@ -import { ECS } from "wolf-ecs"; +import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const A = ecs.defineComponent(); const B = ecs.defineComponent(); const qA = ecs.createQuery(A); - function add(lB) { - for (let i = 0; i < qA.archetypes.length; i++) { - const arch = qA.archetypes[i].entities; + function add() { + const lB = B; + for (let i = 0; i < qA.a.length; i++) { + const arch = qA.a[i].e; for (let j = arch.length - 1; j >= 0; j--) { ecs.addComponent(arch[j], lB); } @@ -17,22 +18,23 @@ export default (count) => { } const qB = ecs.createQuery(B); - function remove(lB) { - for (let i = 0; i < qB.archetypes.length; i++) { - const arch = qB.archetypes[i].entities; + function remove() { + const lB = B; + for (let i = 0; i < qB.a.length; i++) { + const arch = qB.a[i].e; for (let j = arch.length - 1; j >= 0; j--) { ecs.removeComponent(arch[j], lB); } } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { ecs.createEntity(); ecs.addComponent(i, A); } return () => { - add(B); - remove(B); + add(); + remove(); }; -}; +} diff --git a/src/cases/wolf-ecs/entity_cycle.js b/src/cases/wolf-ecs/entity_cycle.js index 13a0bf9..1c754c8 100644 --- a/src/cases/wolf-ecs/entity_cycle.js +++ b/src/cases/wolf-ecs/entity_cycle.js @@ -1,18 +1,19 @@ import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const A = ecs.defineComponent(); const B = ecs.defineComponent(); const qA = ecs.createQuery(A); - function create(lB) { - for (let i = 0, l = qA.archetypes.length; i < l; i++) { - const arch = qA.archetypes[i].entities; + function create() { + const lB = B; + for (let i = 0, l = qA.a.length; i < l; i++) { + const arch = qA.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { - const id1 = ecs.createEntity(); - ecs.addComponent(id1, lB); + const id = ecs.createEntity(); + ecs.addComponent(id, lB); const id2 = ecs.createEntity(); ecs.addComponent(id2, lB); } @@ -21,21 +22,21 @@ export default (count) => { const qB = ecs.createQuery(B); function destroy() { - for (let i = 0, l = qB.archetypes.length; i < l; i++) { - const arch = qB.archetypes[i].entities; + for (let i = 0, l = qB.a.length; i < l; i++) { + const arch = qB.a[i].e; for (let j = arch.length - 1; j >= 0; j--) { ecs.destroyEntity(arch[j]); } } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { ecs.createEntity(); ecs.addComponent(i, A); } return () => { - create(B); + create(); destroy(); }; -}; +} diff --git a/src/cases/wolf-ecs/frag_iter.js b/src/cases/wolf-ecs/frag_iter.js index f455106..a583ff3 100644 --- a/src/cases/wolf-ecs/frag_iter.js +++ b/src/cases/wolf-ecs/frag_iter.js @@ -1,6 +1,6 @@ import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const cmps = []; @@ -12,26 +12,26 @@ export default (count) => { const data = ecs.defineComponent(types.i32); const dataQuery = ecs.createQuery(data); - function dataSystem(lData) { - for (let i = 0, l = dataQuery.archetypes.length; i < l; i++) { - const arch = dataQuery.archetypes[i].entities; + function dataSystem() { + for (let i = 0, l = dataQuery.a.length; i < l; i++) { + const arch = dataQuery.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { - lData[arch[j]] *= 2; + data[arch[j]] *= 2; } } } const zQuery = ecs.createQuery(z); - function zSystem(lZ) { - for (let i = 0, l = zQuery.archetypes.length; i < l; i++) { - const arch = zQuery.archetypes[i].entities; + function zSystem() { + for (let i = 0, l = zQuery.a.length; i < l; i++) { + const arch = zQuery.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { - lZ[arch[j]] *= 2; + z[arch[j]] *= 2; } } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { for (let i = 0; i < cmps.length; i++) { const id = ecs.createEntity(); ecs.addComponent(id, cmps[i]); @@ -42,7 +42,7 @@ export default (count) => { } return () => { - dataSystem(data); - zSystem(z); + dataSystem(); + zSystem(); }; -}; +} diff --git a/src/cases/wolf-ecs/packed_1.js b/src/cases/wolf-ecs/packed_1.js index f2b357b..04720cf 100644 --- a/src/cases/wolf-ecs/packed_1.js +++ b/src/cases/wolf-ecs/packed_1.js @@ -1,6 +1,6 @@ import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const A = ecs.defineComponent(types.u32); @@ -10,16 +10,17 @@ export default (count) => { const E = ecs.defineComponent(types.u32); const q = ecs.createQuery(A); - function sys(lA) { - for (let i = 0, l = q.archetypes.length; i < l; i++) { - const arch = q.archetypes[i].entities; + function sys() { + const lA = A; + for (let i = 0, l = q.a.length; i < l; i++) { + const arch = q.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lA[arch[j]] *= 2; } } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { ecs.createEntity(); ecs.addComponent(i, A); A[i] = 1; @@ -34,6 +35,6 @@ export default (count) => { } return () => { - sys(A); + sys(); }; -}; +} diff --git a/src/cases/wolf-ecs/packed_5.js b/src/cases/wolf-ecs/packed_5.js index adcbcac..76d9649 100644 --- a/src/cases/wolf-ecs/packed_5.js +++ b/src/cases/wolf-ecs/packed_5.js @@ -1,6 +1,6 @@ import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const A = ecs.defineComponent(types.u32); @@ -10,9 +10,10 @@ export default (count) => { const E = ecs.defineComponent(types.u32); const qA = ecs.createQuery(A); - function sysA(lA) { - for (let i = 0, l = qA.archetypes.length; i < l; i++) { - const arch = qA.archetypes[i].entities; + function sysA() { + const lA = A; + for (let i = 0, l = qA.a.length; i < l; i++) { + const arch = qA.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lA[arch[j]] *= 2; } @@ -20,9 +21,10 @@ export default (count) => { } const qB = ecs.createQuery(B); - function sysB(lB) { - for (let i = 0, l = qB.archetypes.length; i < l; i++) { - const arch = qB.archetypes[i].entities; + function sysB() { + const lB = B; + for (let i = 0, l = qB.a.length; i < l; i++) { + const arch = qB.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lB[arch[j]] *= 2; } @@ -30,9 +32,10 @@ export default (count) => { } const qC = ecs.createQuery(C); - function sysC(lC) { - for (let i = 0, l = qC.archetypes.length; i < l; i++) { - const arch = qC.archetypes[i].entities; + function sysC() { + const lC = C; + for (let i = 0, l = qC.a.length; i < l; i++) { + const arch = qC.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lC[arch[j]] *= 2; } @@ -40,9 +43,10 @@ export default (count) => { } const qD = ecs.createQuery(D); - function sysD(lD) { - for (let i = 0, l = qD.archetypes.length; i < l; i++) { - const arch = qD.archetypes[i].entities; + function sysD() { + const lD = D; + for (let i = 0, l = qD.a.length; i < l; i++) { + const arch = qD.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lD[arch[j]] *= 2; } @@ -50,16 +54,17 @@ export default (count) => { } const qE = ecs.createQuery(E); - function sysE(lE) { - for (let i = 0, l = qE.archetypes.length; i < l; i++) { - const arch = qE.archetypes[i].entities; + function sysE() { + const lE = E; + for (let i = 0, l = qE.a.length; i < l; i++) { + const arch = qE.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { lE[arch[j]] *= 2; } } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { ecs.createEntity(); ecs.addComponent(i, A); A[i] = 1; @@ -74,10 +79,10 @@ export default (count) => { } return () => { - sysA(A); - sysB(B); - sysC(C); - sysD(D); - sysE(E); + sysA(); + sysB(); + sysC(); + sysD(); + sysE(); }; -}; +} diff --git a/src/cases/wolf-ecs/query_stress.js b/src/cases/wolf-ecs/query_stress.js new file mode 100644 index 0000000..ac58359 --- /dev/null +++ b/src/cases/wolf-ecs/query_stress.js @@ -0,0 +1,86 @@ +import { ECS, types } from "wolf-ecs"; + +export default function (n) { + const ecs = new ECS(n * 200); + + const cmps = []; + for (let i = 0; i < 7; i++) { + cmps.push(ecs.defineComponent(types.u32)); + } + + const qA = ecs.createQuery(cmps[0]); + const qBC = ecs.createQuery(cmps[1], cmps[2]); + const qBCD = ecs.createQuery(cmps[1], cmps[2], cmps[3]); + const qDEFG = ecs.createQuery(cmps[3], cmps[4], cmps[5], cmps[6]); + + function sysA() { + const lA = cmps[0]; + for (let i = 0, l = qA.a.length; i < l; i++) { + const arch = qA.a[i].e; + for (let j = 0, l = arch.length; j < l; j++) { + lA[arch[j]] *= 2; + } + } + } + + function sysBC() { + const lB = cmps[1]; + const lC = cmps[2]; + for (let i = 0, l = qBC.a.length; i < l; i++) { + const arch = qBC.a[i].e; + for (let j = 0, l = arch.length; j < l; j++) { + lB[arch[j]] *= 2; + lC[arch[j]] *= 2; + } + } + } + + function sysBCD() { + const lB = cmps[1]; + const lC = cmps[2]; + const lD = cmps[3]; + for (let i = 0, l = qBCD.a.length; i < l; i++) { + const arch = qBCD.a[i].e; + for (let j = 0, l = arch.length; j < l; j++) { + lB[arch[j]] *= 2; + lC[arch[j]] *= 2; + lD[arch[j]] *= 2; + } + } + } + + function sysDEFG() { + const lD = cmps[3]; + const lE = cmps[4]; + const lF = cmps[5]; + const lG = cmps[6]; + for (let i = 0, l = qDEFG.a.length; i < l; i++) { + const arch = qDEFG.a[i].e; + for (let j = 0, l = arch.length; j < l; j++) { + lD[arch[j]] *= 2; + lE[arch[j]] *= 2; + lF[arch[j]] *= 2; + lG[arch[j]] *= 2; + } + } + } + + for (let _ = 0; _ < n; _++) { + for (let i = 0; i < 128; i++) { + let e = ecs.createEntity(); + for (let j = 0; j < 7; j++) { + if (i & (1 << j)) { + // Create entities with every possible component combination (n * 2 ^ 7 ents in total) + ecs.addComponent(e, cmps[j]); + } + } + } + } + + return () => { + sysA(); + sysBC(); + sysBCD(); + sysDEFG(); + }; +} diff --git a/src/cases/wolf-ecs/simple_iter.js b/src/cases/wolf-ecs/simple_iter.js index 8628d56..46e8ba9 100644 --- a/src/cases/wolf-ecs/simple_iter.js +++ b/src/cases/wolf-ecs/simple_iter.js @@ -1,6 +1,6 @@ import { ECS, types } from "wolf-ecs"; -export default (count) => { +export default function (n) { const ecs = new ECS(); const A = ecs.defineComponent(types.u32); @@ -13,9 +13,11 @@ export default (count) => { const qCD = ecs.createQuery(C, D); const qCE = ecs.createQuery(C, E); - function sysAB(lA, lB) { - for (let i = 0, l = qAB.archetypes.length; i < l; i++) { - const arch = qAB.archetypes[i].entities; + function sysAB() { + const lA = A; + const lB = B; + for (let i = 0, l = qAB.a.length; i < l; i++) { + const arch = qAB.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { const temp = lA[arch[j]]; lA[arch[j]] = lB[arch[j]]; @@ -24,9 +26,11 @@ export default (count) => { } } - function sysCD(lC, lD) { - for (let i = 0, l = qCD.archetypes.length; i < l; i++) { - const arch = qCD.archetypes[i].entities; + function sysCD() { + const lC = C; + const lD = D; + for (let i = 0, l = qCD.a.length; i < l; i++) { + const arch = qCD.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { const temp = lC[arch[j]]; lC[arch[j]] = lD[arch[j]]; @@ -35,9 +39,11 @@ export default (count) => { } } - function sysCE(lC, lE) { - for (let i = 0, l = qCE.archetypes.length; i < l; i++) { - const arch = qCE.archetypes[i].entities; + function sysCE() { + const lC = C; + const lE = E; + for (let i = 0, l = qCE.a.length; i < l; i++) { + const arch = qCE.a[i].e; for (let j = 0, l = arch.length; j < l; j++) { const temp = lC[arch[j]]; lC[arch[j]] = lE[arch[j]]; @@ -46,7 +52,7 @@ export default (count) => { } } - for (let i = 0; i < count; i++) { + for (let i = 0; i < n; i++) { const ab = ecs.createEntity(); ecs.addComponent(ab, A); ecs.addComponent(ab, B); @@ -70,8 +76,8 @@ export default (count) => { } return () => { - sysAB(A, B); - sysCD(C, D); - sysCE(C, E); + sysAB(); + sysCD(); + sysCE(); }; -}; +}