我刚刚在360和WP7上运行了我的2D精灵游戏,而且它比Windows版本的速度慢得多。 FPS大概是一帧一秒,但在窗户上它很流畅。我在这里使用的是最新版本的Farseer。这两个平台上有什么东西可能导致如此剧烈的放缓吗?
提前致谢。
答案 0 :(得分:4)
是。这两个平台上存在着可能导致显着减速的绝对事物。 360和WP7上的CLR比垃圾收集器慢得多。因此,这两个平台的性能可能会有很大差异。在PC上以60 fps运行的游戏可以在这些平台上减慢到每秒1-2 fps的爬行速度。
有很多资源用于解决问题并优化代码以在所有三个平台上获得相同的FPS。以下是我推荐的内容。
首先,查看Shawn Hargreave关于“How to tell if your Garbage collection is too slow”的文章。这将首先回答这是否是你所看到的。
然后点击Ian Nicolades关于“High End Performance Optimizations for Xbox360 and WP7”的文章。该文章中有很多好的建议,提示和技巧。其中大部分应该有助于消除您目前遇到的任何性能问题。
Stack Overflow上还有一些好帖子我建议你仔细阅读: Game Jitters on xBox360 XNA game performance
同样对于一些好的阅读,.NET Compact框架团队(WP7和360运行紧凑框架的修改版本)在Xbox 360上有一些关于托管代码性能的古老而又好的文章Part1& ; Part2
还有一些关于此事的好文章来自战壕中的人。之前在360和WP7上发布游戏的人。这是我最喜欢的Kris Steele之一,他在XNA的多个平台上发布了名为“Optimizing Code for Xbox XNA Games is required”的游戏。
然后最后但并非最不重要的是,App Hub论坛上有大量帖子涵盖从WP7到Xbox表现的所有表现领域。不幸的是,App Hub上的搜索不是很好,但帖子就在那里,提供各种提示/技巧以及如何在这些平台上查找和改进游戏性能的建议。
答案 1 :(得分:2)
我完全同意George Clingerman,360和WP7上的CLR垃圾收集器比PC上慢得多。
首先,我建议您了解垃圾收集器的工作原理(不是那么难)。
基本步骤是: 1.验证 2.简介 3.找到 4.修复
在这里,您可以找到有关如何使用CLRProfiler执行此操作的分步说明(基本)http://spacedjase.com/post/2010/07/02/How-to-eliminate-frame-by-frame-Garbage-Generation-using-CLR-Profiler.aspx
CLR Profiler使您可以查看进程的托管堆并调查垃圾收集器的行为。使用该工具中的各种视图,您可以获得有关应用程序的执行,分配和内存消耗的有用信息。 (下载http://www.microsoft.com/download/en/details.aspx?id=16273)
以下是我在互联网上找到的最有用的链接:
并且总结了我认为最重要的问题:
不要使用linq 不要使用LINQ。它看起来很酷。它使您的代码更短,更简单,甚至更容易阅读。但LINQ查询很容易成为垃圾的重要来源。它们在您的启动代码中都很好,因为无论如何只需加载资源和准备游戏资源就会产生垃圾。但是不要在Update,Draw或在游戏过程中调用的任何其他方法中使用它。
显示字符串而不触发垃圾回收回复引用 尽量减少使用ToString()。它至少会创建一个生活在堆上的字符串。请参阅上文,了解如何在不产生任何垃圾的情况下将int绘制到屏幕上。如果确实需要使用ToString,请尝试限制它的调用频率。如果字符串仅更改每个级别,则仅在级别的开头生成一次。如果它仅在某个值更改时更改,则仅在该值更改时生成它。你能提出的任何限制都是值得的。检查布尔条件所花费的时间非常少,几乎不存在。在GC可以在复杂堆上运行的时间内,您可能需要进行数十甚至数十万次真/假检查。 http://forums.create.msdn.com/forums/p/45512/273330.aspx#273330 http://spacedjase.com/post/2010/09/16/Garbage-safe-number-to-string-conversion.aspx 小心字符串格式。在不引起分配的情况下很难在.NET中操作字符串。
不要分配内存(呃!) 这很简单:不要在引用类型上调用new。但是,可以使用Matrix,Vector3和Color等新值类型。 每当您发现自己想要新建引用类型时,请使用对象池来重用现有实例。 oncreators.xna.com上的粒子和音频3D示例使用此技术,SwampThingTom在博客上发布了可重用的池集合。 http://swampthingtom.blogspot.com/2007/06/generic-pool-collection-class.html http://spacedjase.com/post/2010/07/02/Generic-Resource-Pool.aspx
请勿使用代表您分配的课程 将数据添加到集合类(如List或Dictionary)时,可能必须分配内存以扩展集合。您可以通过使用具有显式容量参数的集合构造函数重载来避免这种情况。指定一个容量,以预先分配您打算存储在集合中的最大对象数量所需的内存。
不要让CLR运行时分配 当装箱发生时,CLR运行时分配内存。像瘟疫一样避免这种情况!拳击可能由于许多原因而发生,一些显而易见,另一些则不那么: •如果为对象变量指定值类型,则会将其装箱。 •如果将值类型存储在其中一个旧的非泛型集合类中,则它们将被装箱。 •通过接口访问值类型会导致它们被装箱。 •如果使用枚举类型作为字典键,内部字典操作将导致装箱。您可以通过使用整数键来避免这种情况,并在将枚举值添加到字典之前将其枚举为整数
阿根廷的问候 HERNAN