当前位置: 首页 > 编程语言 > C#

C#中“新”的性能成本?分享

时间:2023-04-11 00:38:21 C#

C#中“新”的性能成本?在C#中,使用new关键字的性能成本是多少?我特别提到了与游戏开发相关的问题,我知道在C++新手中,每个更新周期都是绝对禁止的。这同样适用于C#吗?我正在使用XNA并为移动设备开发。只是真的问一个优化问题。new的成本分为三个部分:如果不在主代码中创建任何新对象,很难以惯用的方式使用C#……尽管我敢说尽可能多地重用对象是可行的。试着拿一些真实的设备,看看你的游戏表现如何。我当然同意在编程中通常要避免像这样的微优化,但它比其他地方更适合游戏循环——因为显然游戏对即使是很小的停顿也非常敏感。然而,判断使用更多对象的成本可能非常困难,因为它会随着时间的推移由GC成本分摊。.NET中的分配器和垃圾收集器非常好,尽管它在设备上可能更简单(我认为是WindowsPhone7)?特别是,我不确定CompactFrameworkCLR(WP7使用的)是否具有分代GC。C#中的分配实际上比C++中更快。它只涉及递增堆指针并返回该指针。一般来说,对象在C#中比在C++中更频繁地被更新,因为在字符串等中有更多不可变的东西。正如其他人所指出的,真正的野兽是垃圾收集器,它有点棘手。尽管如此,在大多数情况下,即使是GCing也比C++中的delete更快——只是您无法预测它何时会发生。来自.NET团队成员RicoMariani的一些提示:http://msdn.microsoft.com/en-us/library/ms973837.aspx它有点陈旧,对GC进行了一些改进,但大部分信息是仍然相关。我应该补充一点,虽然XNA/CompactFramework垃圾收集器比x86版本稍微慢一些,以便牺牲CPU来换取内存性能,所以你应该意识到这一点。EDIT我忘了提,这很重要:值类型,包括结构,也使用新语法,但它们是在堆栈而不是堆上创建的,所以除非你打包它们,否则没有GC成本。新运营商本身的成本可以忽略不计。可能产生的成本是在自定义构造函数中处理。所以如果你在这个构造函数中有很多事情要做,那可能是个问题。您应该始终以尽可能“最简单”的方式编码,然后测量瓶颈(如果存在)。无论如何,我永远不会用C#编写游戏。编辑因为它引起了不满,我的意思是如果C++是可用的选项,我永远不会用C#编写代码。这就是我的想法,因为OP还标记了C++。new本身的成本可能并不重要,但在游戏中当在堆上分配新对象(创建引用类型的实例时)可能会触发垃圾收集时,副作用可能很重要。如果担心GC,可以使用值类型或重用对象。此外,正如Darin正确指出的那样,构造函数可以做很多工作。在C#中,内存由垃圾收集器进行碎片整理,因此查找和分配内存是一项非常快速的操作。但是,GC偶尔执行的碎片整理会大大降低运行速度。在C#中,new运算符几乎没有相关成本,但是当您在引用类型上使用new时,那里会有一个堆分配,由GC。如果内存是连续的,那么分配内存只是指针移动,但如果在两次分配之间发现GAP,那么GC将查询可用内存的空闲列表(链表)以找到所需的对象,这将需要一些时间查询o(ntraveltime。请参阅EricLippert的帖子当您在c#中编写新内容时,CLR会将内存分配给托管堆上的对象。查看此链接以获取更多信息:http://msdn.microsoft.com/en-us/library/ee787088(v=vs.100).aspx由于垃圾收集在C#中是自动的(只有在测试期间人们使用GC.Collect手动触发它时),在C#游戏设计是一个坏主意。你应该寻找C++,因为你有析构函数。~ClassName(){//killmyobjectandreclaimmemory.}我的测量表明,引用类型的“新”有时需要2.2秒,有时可能快几滴答。底线是.netGC中没有实时保证,性能随机变化很大。所以我建议实时设计,例如游戏,不要在代码的实时部分引用“新”引用类型(例如更新循环),因为没有实时保证。当然,许多人会争辩说,如果“新”仅在几个小时内发生一次,则需要2.2秒才能让“新”更重要。那必须是设计师的判断。但是对于学术论点,GC不是实时的,所以不要在实时代码中称它为“new”。以上是C#学习教程:C#“新”的性能代价?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: