首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >‘给我制造了很多垃圾,能帮上忙吗?

‘给我制造了很多垃圾,能帮上忙吗?
EN

Stack Overflow用户
提问于 2011-04-29 14:52:48
回答 2查看 3.1K关注 0票数 9

我正在开发一个Xbox 360游戏与XNA。我真的很想在几个地方使用C#的yield return构造,但是它似乎会产生很多垃圾。

代码语言:javascript
运行
AI代码解释
复制
class ComponentPool<T> where T : DrawableGameComponent
    {
    List<T> preallocatedComponents;

    public IEnumerable<T> Components
        {
        get
            {
            foreach (T component in this.preallocatedComponents)
                {
                // Enabled often changes during iteration over Components
                // for example, it's not uncommon for bullet components to get
                // disabled during collision testing
                // sorry I didn't make that clear originally
                if (component.Enabled)
                    {
                    yield return component;
                    }
                }
            }
        }
    ...

我在任何地方都使用这些组件池--用于子弹、敌人、爆炸;任何数量众多且短暂的东西。我经常需要循环它们的内容,而且我只对那些活动的组件(即Enabled == true)感兴趣,这就是Components属性的行为。

目前,在使用这种技术时,我看到了每秒高达800 K的额外垃圾。这可以避免吗?还有其他方式使用yield return吗?

编辑:我发现了这个问题关于如何在资源池上迭代而不创建垃圾这一更广泛的问题。许多评论者对此不屑一顾,显然不理解Compact的局限性,但这个评论员更有同情心,建议创建迭代器池。这就是我要用的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-29 18:11:07

编译器实现迭代器确实使用类对象,使用使用yield return实现的迭代器(例如使用foreach )确实会导致分配内存。在事物的方案中,这很少是一个问题,因为要么是在迭代时完成大量的工作,要么是分配了相当多的内存在迭代时执行其他事情。

为了使迭代器分配的内存成为一个问题,您的应用程序必须是数据结构密集型的,并且您的算法必须在对象上操作而不分配任何内存。想想类似的生命游戏。突然之间,迭代本身压倒了一切。当迭代分配内存时,可以分配大量的内存。

如果您的应用程序符合此配置文件(并且只有当),那么您应该遵循的第一条规则是:

  • 当一个简单的迭代概念可用时,避免内部循环中的迭代器。

例如,如果您有类似于数据结构的数组或列表,那么您已经公开了一个indexer属性和一个count属性,这样客户端就可以简单地使用For循环,而不是在您的迭代器中使用foreach。这是减少GC的“容易的钱”,它不会使您的代码丑陋或臃肿,只是稍微不那么优雅。

你应该遵循的第二个原则是:

  • 度量内存分配,以查看何时何地使用第一条规则。
票数 5
EN

Stack Overflow用户

发布于 2011-04-29 16:39:39

对于grins,尝试在Linq查询中捕获过滤器并保持查询实例。这可能会减少每次枚举查询时的内存重新分配。

如果没有其他的话,那么preallocatedComponents.Where(r => r.Enabled)语句的代码要少得多,这样就可以完成与收益率返回相同的事情了。

代码语言:javascript
运行
AI代码解释
复制
class ComponentPool<T> where T : DrawableGameComponent
    {
    List<T> preallocatedComponents;
    IEnumerable<T> enabledComponentsFilter;

    public ComponentPool()
    {
       enabledComponentsFilter = this.preallocatedComponents.Where(r => r.Enabled);
    }

    public IEnumerable<T> Components
        {
        get { return enabledComponentsFilter; }
        }
    ...
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5838177

复制
相关文章

相似问题

领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文