简体   繁体   English

距离检查性能

[英]Distance checking performance

I've been learning C#/XNA in an attempt to make a game for the past few weeks so maybe this is an obvious newbie thing, but here goes: 在过去的几周里,我一直在学习C#/ XNA,以尝试制作一款游戏,所以也许这显然是新手,但是这里是:

I've been making a fairly simple 2D game, so I have a list of ~1000 objects (NPC's), and I'm iterating through them extremely frequently to do distance checking on each one. 我一直在做一个相当简单的2D游戏,所以我有大约1000个对象(NPC)的列表,并且我非常频繁地遍历它们以对每个对象进行距离检查。 The problem is when I increase the distances, everything slows down considerably to the point where the game is unplayable, and I don't really understand why. 问题是,当我增加距离时,一切都会大大降低,直到无法玩游戏,而我却真的不明白为什么。

It works fine when the distances are short (if all objects are within one 800x480 world size), but when they are increased (say, an 8000x4800 world size), my performance tanks. 当距离很短时(如果所有对象都在一个800x480的世界范围内),它可以很好地工作;但是当距离增加时(例如,一个8000x4800的世界范围),我的性能很出色。

Here is some relevant code (not all of it, obviously, since that would be too much stuff, but this is the gist of what's happening): 这是一些相关的代码(显然,并不是全部,因为这会太多,但这是正在发生的事情的要旨):

List<Human> humans;
List<Enemy> enemies;

public void Update(City city, float gameTime)
{
    humans = city.GetHumans();
    enemies = city.GetEnemies();

    for (int h = 0; h < humans.Count; h++)
    {
        Vector2 human_position = humans[h].position;

        Vector2 nearestEnemyPosition = Vector2.Zero;

        for (int e = 0; e < enemies.Count; e++)
            {
                Vector2 enemy_position = enemies[e].position;
                float distanceToEnemy = Vector2.DistanceSquared(human_position, enemy_position);

                if (distanceToEnemy < distanceToNearestEnemy)
                {
                    distanceToNearestEnemy = distanceToEnemy;
                    nearestEnemyPosition = enemy_position;
                }

                if (distanceToNearestEnemy < 2500f)
                {
                     logic code here (very little performance impact)
                }
            }

        for (int hh = 0; hh < humans.Count; hh++)
            {
                if (h == hh)
                {
                    continue;
                }

                if (humanMoved == true)
                {
                    continue;
                }

                Vector2 other_human_position = humans[hh].position;

                if (Vector2.DistanceSquared(human_position, other_human_position) < 100f)
                {
                   do more stuff here (movement code, no performance impact)
                }

I also have almost identical loops for the enemy list. 对于敌人列表,我也有几乎相同的循环。

The code to make them is here: 制作它们的代码在这里:

foreach (Human human in this.humans)
        {
            Vector2 position = new Vector2(random.Next(800), random.Next(480));
            human.Spawn(position);
        }

This works fine. 这很好。 I get 60fps and it's totally smooth & everything runs perfectly. 我得到60fps,并且完全流畅,一切运行正常。 However, if I do this: 但是,如果我这样做:

foreach (Human human in this.humans)
        {
            Vector2 position = new Vector2(random.Next(8000), random.Next(4800));
            human.Spawn(position);
        }

Everything tanks and I get 1fps. 一切坦克,我得到1fps。 This seems very strange, do bigger numbers really make the DistanceSquared function take longer to compute? 这似乎很奇怪,更大的数字确实会使DistanceSquared函数花费的时间更长吗? Why? 为什么? Or is there something else that could be causing this that I am missing? 还是有其他原因可能导致我失踪?

I've already run a couple performance profilers and they told me nothing useful, just that DistanceSquared is taking up the vast majority of my CPU cycles. 我已经运行了几个性能分析器,他们告诉我没有什么用,只是DistanceSquared占用了我的CPU周期的绝大部分。 If it's at the normal value of 800x480, only 38% of my game time is spent in that loop. 如果将其设置为800x480的正常值,则我的游戏时间只有38%花费在该循环中。 When I change the numbers from 800->8000/480->4800, 90% of my time is spent in the loop. 当我将数字从800-> 8000 / 480-> 4800更改时,我90%的时间都花在循环中。 It's not like there are more objects to call, or more math to do, it's the same math, just with bigger numbers, so why is there such a dramatic difference? 并不是要调用更多的对象,也不是要执行更多的数学运算,就不是相同的数学运算,只是数字更大,所以为什么会有如此巨大的差异?

尝试在计算之前将您的世界归一化为[0-1,0-1],看看它是否有影响,这样您的循环代码将完全相同,每个位置都将在0-1范围内,并计算真实世界位置只是在计算结束时将它们相乘

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM