XNA 中 Game.Services.GetService() 的效率

发布于 2024-11-28 09:48:13 字数 339 浏览 1 评论 0原文

本质上,我试图找出是否应该存储对我检索的服务的引用,或者是否可以在每次需要时简单地调用 GetService。

我使用它的一个完美例子是 SpriteBatch。我没有让对象存储对 SpriteBatch 的引用,而是

    SpriteBatch spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); 

在每个需要它的 Draw() 方法的开头调用它。

总而言之,GetService()的大O是什么?这将帮助我做出决定。我假设它是一个哈希表,所以通常是 O(1)?

Essentially I'm trying to find out whether I should be storing a reference to the service I retrieve or if I can simply call GetService every time I need it.

A perfect example of what I'm using this with is SpriteBatch. Instead of having an object store a reference to the SpriteBatch, I call

    SpriteBatch spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch)); 

at the beginning of every Draw() method that needs it.

In conclusion, what is the Big O of GetService()? This will help me decide. I'm assuming it's a hash table so generally O(1)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

内心激荡 2024-12-05 09:48:13

GetService 的 Big-O 是无关紧要的,因为其中有少量且恒定数量的服务。因此,有效调用 GetService 是一个常数时间 O(1) 操作。 (它内部使用字典 - 我无法轻松地在其 Big-O 上找到明确的答案,但我认为它非常好)。

它比获取参考文献慢很多吗? 是的。

对于拥有 100 个游戏对象的游戏世界来说,它是否太慢否。

对于粒子系统中的 100000 个粒子来说,速度是否太慢?是的。

即使您忽略性能并仅考虑架构观点,使用服务架构是否是一个坏主意? 是的。

The Big-O of GetService is irrelevant, because you have a small and constant number of services in there. So effectively calling GetService is a constant-time O(1) operation. (Internally it uses a Dictionary - I couldn't easily track down a definitive answer on its Big-O, but I imagine it's pretty good).

Is it a lot slower than getting a reference? Yes.

Is it too slow for a game world with, say, 100 gameplay objects? No.

Is it too slow for each of 100000 particles in a particle system? Yes.

Is using a services architecture for this a bad idea, even if you ignore performance and consider only an architectural point of view? Yes.

゛时过境迁 2024-12-05 09:48:13

不能说我对 GetService 的渐近效率一无所知,但显而易见的是,它肯定比维护对象的引用要慢。至少,这应该是显而易见的,因为引用只是坐在那里,等待使用,而 GetService 需要从其中检索 Type 实例一个类,然后在使用的任何集合中查找该 Type,最后转换为正确的类型,从而引发运行时检查等。

就个人而言,这些都不是问题。即使所有这些都在一起,如果只使用几次,也不会出现问题。但是,看看您如何在每帧的基础上检索这些内容,影响可能会变得明显,具体取决于您每帧检索的服务数量。

根据我所掌握的有关您的代码的少量信息,我想说更改参考选项应该不那么困难。但要真正决定是否值得,也许可以尝试转而保留参考(至少对于几个服务而言)并检查 FPS 变化了多少。或者,添加一些无关的 GetService 调用,看看它会导致 FPS 下降多少。这将是一个更明确的方式来找出改变一切的重要性。

Can't say I know anything about the the asymptotic efficiency of GetService, but the obvious thing is that it's guarenteed to be slower than maintaining a reference to the object. At least, this should be obvious, as a reference is just sitting there, waiting to be used, whilst GetService requires retrieving a Type instance from a class, then looking up that Type in whatever collection is used, and finally casting to the correct type, incurring runtime checks and such.

Individually, none of these things is a problem. Even all together, none of them are a problem if only used a few times. But seeing as how you are retrieving these on a per-frame basis, the hit could become apparent, depending on how many services you are retrieving each frame.

Based on the small amount of information I have about your code, I would say that changing to the reference option shouldn't be that hard. But to really decide on whether it's worth it, maybe try to switching to keeping a reference (at least for a couple of services) and checking on how much your FPS changes. Alternatively, throw in some extraneous GetService calls and see how much of a drop in FPS it causes. That would be a more definitive way to find out the importance of changing everything over.

避讳 2024-12-05 09:48:13

如果 SpriteBatch 的 this 实例是您整个模拟过程中所需要的,我认为您应该将其存储在 Services 中。我认为如果你正确使用 GameServiceContainer,你就不必为速度而烦恼。
例如:在我的模拟中,我有大约 20 个游戏服务,必须可供许多游戏组件使用。这些服务中的大多数是在调用Initialize()时从Services中提取的,因为实例在运行时不会改变。唯一可能改变的服务(在我的模拟中)是 ICamera 和 IGlobalLight。因此,这些是每次 Draw() 时从服务中提取的唯一引用。

最后,我认为与超级全局变量或使所有服务单例这样的“架构解决方案”相比,性能开销是值得的。

If the this instance of a SpriteBatch is something you need through your whole simulation, I think you should store it in Services. I think if you use the GameServiceContainer correctly, you don't have to bother with Speed.
E.g: in my simulation I have about 20 GameServices that have to be available to lots of GameComponents. The most of these services are extracted from Services while calling Initialize(), because the instance don't change during runtime. The only Services that might change (in my simulation) are ICamera und IGlobalLight. So these are the only references that are extracted from Services on every Draw().

Finally I think the performance overhead is worth it, compared to a "architectural solution" like super global variables or making all Services Singletons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文