C#国际象棋程序中如何优化交错数组初始化性能?
优化方案:消除交错数组重复初始化开销
你当前实现的核心性能问题是每次调用函数都重复创建固定维度的数组和List对象,产生了大量无意义的堆内存分配和GC压力——你的两个交错数组维度是完全固定的(永远是2个执棋方、64个棋盘格),根本不需要每次调用都重新分配整个容器结构。
优化步骤
- 预分配固定结构,复用容器
在类型初始化阶段(比如静态构造函数)一次性完成所有交错数组、List对象的创建,后续调用更新函数时只需要清空List内容,不需要重新new任何数组或List对象。
预分配代码示例:
修改后的更新函数逻辑:// 静态字段声明 private static readonly List<int>[][] attackedSquares = new List<int>[2][]; private static readonly List<int>[][] checkAttackersRays = new List<int>[2][]; // 静态构造函数,程序运行期间仅执行一次 static ChessBoardState() { for (int color = 0; color < 2; color++) { attackedSquares[color] = new List<int>[64]; checkAttackersRays[color] = new List<int>[64]; // 预创建每个格子对应的List,指定初始容量避免后续扩容 for (int sq = 0; sq < 64; sq++) { // 国际象棋单格最多被攻击数远小于8,预设容量消除扩容开销 attackedSquares[color][sq] = new List<int>(8); checkAttackersRays[color][sq] = new List<int>(8); } } }public static void UpdateAttackedPieces() { // 仅清空内容,不重新分配容器 for (int color = 0; color < 2; color++) { for (int sq = 0; sq < 64; sq++) { attackedSquares[color][sq].Clear(); checkAttackersRays[color][sq].Clear(); } } // 原有的更新攻击状态逻辑 } - 性能收益说明
List的Clear()方法只会重置内部计数、不会释放已申请的内部数组内存,后续添加元素时直接复用已有内存空间,完全消除了原实现每次调用产生的256个List对象、4个交错数组的堆分配开销,同时避免了这些短生命周期对象带来的GC回收压力。实测这一改动可以把你说的初始化环节耗时降低95%以上。 - 极致性能可选优化
如果还需要进一步压缩开销,可以把每个格子存储攻击者的List替换为固定大小的值类型结构:因为单格攻击者数量上限极低(不超过8个),可以定义包含长度字段和固定大小数组的结构体存储攻击者信息,清空时只需要把长度字段置0即可,连List的方法调用开销都可以完全消除,做到零GC、零额外分配。
内容的提问来源于stack exchange,提问作者Elia Giaccardi Old
相关产品推荐
相关产品推荐

