Files
esengine/tests/ECS/Core/InitializationComparison.performance.test.ts
YHH f3dc8c6344 BigIntFactory 缓存优化
- 为 zero() 和 one() 方法添加缓存,避免重复创建对象
ComponentIndexManager 优化
  - 添加了空实体检查,跳过不必要的索引操作
  - 实现了 Set 对象池,重用 Set 实例以减少内存分配
  - 优化了自动优化检查频率,从每次操作变为每100次操作检查一次
EntityManager 优化
  - 对空实体跳过不必要的组件索引、原型系统和脏标记操作
  - 批量创建时同样应用空实体优化
2025-07-30 17:10:58 +08:00

176 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Entity } from '../../../src/ECS/Entity';
import { BigIntFactory } from '../../../src/ECS/Utils/BigIntCompatibility';
import { ComponentType } from '../../../src/ECS/Core/ComponentStorage';
describe('初始化方式性能对比', () => {
test('对比不同初始化方式的性能', () => {
const testCount = 10000;
console.log(`\n=== 初始化方式对比 (${testCount}个实体) ===`);
// 方式1字段直接初始化原来的方式
class EntityWithFieldInit {
public name: string;
public id: number;
private _componentMask = BigIntFactory.zero();
private _componentTypeToIndex = new Map<ComponentType, number>();
constructor(name: string, id: number) {
this.name = name;
this.id = id;
}
}
// 方式2构造函数初始化新方式
class EntityWithConstructorInit {
public name: string;
public id: number;
private _componentMask: any;
private _componentTypeToIndex: Map<ComponentType, number>;
constructor(name: string, id: number) {
this.name = name;
this.id = id;
this._componentMask = BigIntFactory.zero();
this._componentTypeToIndex = new Map<ComponentType, number>();
}
}
// 方式3完全延迟初始化
class EntityWithLazyInit {
public name: string;
public id: number;
private _componentMask: any;
private _componentTypeToIndex: Map<ComponentType, number> | undefined;
constructor(name: string, id: number) {
this.name = name;
this.id = id;
// 什么都不初始化
}
private ensureInit() {
if (!this._componentTypeToIndex) {
this._componentMask = BigIntFactory.zero();
this._componentTypeToIndex = new Map<ComponentType, number>();
}
}
}
// 测试方式1字段直接初始化
let startTime = performance.now();
const entities1 = [];
for (let i = 0; i < testCount; i++) {
entities1.push(new EntityWithFieldInit(`Entity_${i}`, i));
}
const fieldInitTime = performance.now() - startTime;
// 测试方式2构造函数初始化
startTime = performance.now();
const entities2 = [];
for (let i = 0; i < testCount; i++) {
entities2.push(new EntityWithConstructorInit(`Entity_${i}`, i));
}
const constructorInitTime = performance.now() - startTime;
// 测试方式3延迟初始化
startTime = performance.now();
const entities3 = [];
for (let i = 0; i < testCount; i++) {
entities3.push(new EntityWithLazyInit(`Entity_${i}`, i));
}
const lazyInitTime = performance.now() - startTime;
// 测试方式4只创建基本对象
startTime = performance.now();
const entities4 = [];
for (let i = 0; i < testCount; i++) {
entities4.push({ name: `Entity_${i}`, id: i });
}
const basicObjectTime = performance.now() - startTime;
console.log(`字段直接初始化: ${fieldInitTime.toFixed(2)}ms`);
console.log(`构造函数初始化: ${constructorInitTime.toFixed(2)}ms`);
console.log(`延迟初始化: ${lazyInitTime.toFixed(2)}ms`);
console.log(`基本对象创建: ${basicObjectTime.toFixed(2)}ms`);
console.log(`\n性能对比:`);
console.log(`构造函数 vs 字段初始化: ${(fieldInitTime / constructorInitTime).toFixed(2)}x`);
console.log(`延迟 vs 构造函数: ${(constructorInitTime / lazyInitTime).toFixed(2)}x`);
console.log(`延迟 vs 基本对象: ${(lazyInitTime / basicObjectTime).toFixed(2)}x`);
});
test('测试BigIntFactory.zero()的性能', () => {
const testCount = 10000;
console.log(`\n=== BigIntFactory.zero()性能测试 ===`);
// 测试1每次调用BigIntFactory.zero()
let startTime = performance.now();
const values1 = [];
for (let i = 0; i < testCount; i++) {
values1.push(BigIntFactory.zero());
}
const directCallTime = performance.now() - startTime;
// 测试2重复使用同一个实例
const sharedZero = BigIntFactory.zero();
startTime = performance.now();
const values2 = [];
for (let i = 0; i < testCount; i++) {
values2.push(sharedZero);
}
const sharedInstanceTime = performance.now() - startTime;
// 测试3使用数字0
startTime = performance.now();
const values3 = [];
for (let i = 0; i < testCount; i++) {
values3.push(0);
}
const numberZeroTime = performance.now() - startTime;
console.log(`每次调用BigIntFactory.zero(): ${directCallTime.toFixed(2)}ms`);
console.log(`重复使用同一实例: ${sharedInstanceTime.toFixed(2)}ms`);
console.log(`使用数字0: ${numberZeroTime.toFixed(2)}ms`);
console.log(`性能提升:`);
console.log(`共享实例 vs 每次调用: ${(directCallTime / sharedInstanceTime).toFixed(2)}x faster`);
console.log(`数字0 vs BigIntFactory: ${(directCallTime / numberZeroTime).toFixed(2)}x faster`);
});
test('测试Map创建的性能', () => {
const testCount = 10000;
console.log(`\n=== Map创建性能测试 ===`);
// 测试1每次new Map()
let startTime = performance.now();
const maps1 = [];
for (let i = 0; i < testCount; i++) {
maps1.push(new Map());
}
const newMapTime = performance.now() - startTime;
// 测试2使用对象字面量
startTime = performance.now();
const objects = [];
for (let i = 0; i < testCount; i++) {
objects.push({});
}
const objectTime = performance.now() - startTime;
// 测试3延迟创建Map
startTime = performance.now();
const lazyMaps = [];
for (let i = 0; i < testCount; i++) {
lazyMaps.push(null); // 先不创建
}
const lazyTime = performance.now() - startTime;
console.log(`每次new Map(): ${newMapTime.toFixed(2)}ms`);
console.log(`对象字面量: ${objectTime.toFixed(2)}ms`);
console.log(`延迟创建: ${lazyTime.toFixed(2)}ms`);
console.log(`性能对比:`);
console.log(`对象 vs Map: ${(newMapTime / objectTime).toFixed(2)}x faster`);
console.log(`延迟 vs Map: ${(newMapTime / lazyTime).toFixed(2)}x faster`);
});
});