gpt4 book ai didi

c# - List.AddRange 导致了短暂的延迟

转载 作者:行者123 更新时间:2023-11-30 14:35:17 27 4
gpt4 key购买 nike

我有一个实现 ICollidable 接口(interface)的实体列表。该接口(interface)用于解决实体之间的冲突。因此,我的实体是:

  • 球员
  • 敌人
  • 射弹
  • 项目
  • 瓷砖

在每次游戏更新时(大约 60 t/s),我都会清除列表并根据游戏状态添加当前实体。我通过以下方式完成此操作:

collidableEntities.Clear();
collidableEntities.AddRange(players);
collidableEntities.AddRange(enemies);
collidableEntities.AddRange(projectiles);
collidableEntities.AddRange(items);
collidableEntities.AddRange(camera.VisibleTiles);

一切正常,直到我将可见的图 block 添加到列表中。运行游戏循环的前 1-2 秒会导致明显的打嗝,从而延迟绘制(因此我可以在渲染中看到抖动)。我可以从字面上删除/添加添加图 block 的行,并查看抖动的发生和不发生,因此我已将范围缩小到该行。

我的问题是,为什么? VisibleTiles 列表大约有 450-500 个图 block ,因此数据量确实不大。每个图 block 包含一个 Texture2D(图像)和一个 Vector2(位置)以确定渲染的内容和位置。我会继续寻找,但从我的头顶开始,我不明白为什么只有前 1-2 秒会打嗝,但从那以后就很顺利了。

如有任何建议,我们将不胜感激。

更新

我曾尝试将初始容量增加到大约数量的元素,但没有观察到任何差异。

更新

根据要求,这里是camera.VisibleTiles的代码

public List<Tile>
{
get { return this.visibleTiles; }
}

最佳答案

每当遇到这样的性能问题时,正确的 react 是不要猜测可能的原因;正确的响应是分析应用程序。有多种选择;我相信您可以在 StackOverflow 上找到建议。

不过,今天我很幸运,所以我将忽略我刚刚给你的建议并进行大胆的猜测。我将解释我的推理,希望对以后诊断此类问题有所帮助。

事实上你描述的问题只发生一次并且只在游戏开始时让我相信这不是列表本身功能固有的任何东西, 或碰撞逻辑。当然,这是假设列表中的对象数量在这段时间内基本保持不变。如果它由其中任何一个引起的,我希望它每一帧都会发生。

因此我怀疑垃圾收集器。您可能会在游戏开始时看到 GC 发生——换句话说,就在您将所有海量 Assets 加载到内存之后。您也可能会在代码中看似随机的点看到它发生,因为理论上您分配的任何对象都可以将它推到集合的边缘。

我的猜测是:当您加载游戏时,您创建的 Assets 会产生大量收集压力,但仍不足以触发收集。当您在游戏过程中分配对象时(在本例中,是调整列表大小的结果),收集压力会增加到 GC 最终决定激活的程度,从而导致您观察到的抖动。一旦 GC 运行,并且所有适当的对象都被降级到它们正确的世代,抖动就会停止。

正如我所说,这只是一个猜测,尽管是一个有根据的猜测。然而,它很容易测试。在进入渲染循环之前添加对 GC.Collect(2) 的调用。如果我是对的,抖动应该消失了。

如果您想比这更彻底 - 我强烈推荐它 - Microsoft 提供了一个对调试内存问题很有用的工具,CLR Profiler .该工具将向您准确显示收集发生的时间和原因。它对 XNA 开发非常有用。

关于c# - List<T>.AddRange 导致了短暂的延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12391956/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com