C # (.Net 2.0) Micro Optimization Part 2: Finding Adjacent Groups in a Grid

I have a very simple function that takes the corresponding bit field, grid and square. It was used to use the delegate, but I re-encoded a lot and finished the operation with the bit field &in order to avoid delegation, while maintaining the ability to perform the corresponding coordination. Basically, the task is to find all adjacent elements in the grid that correspond to the bit field match, starting from a certain square "leader". A square is a somewhat small (but not tiny) class. Any tips on how to do this even faster? Note that the grid itself is quite small (500 elements in this test).

Edit: It is worth noting that this function is called more than 200,000 times per second. In truth, in the end, my goal will be to call it less often, but it is very difficult, given that my ultimate goal is for the grouping system to be processed with scripts and not be hardcoded. However, this function will always be called more than any other function.

Edit: To clarify, the function does not check if it matches the leaderbitfield by design. The goal is that the leader is not required to match the bitfield (although in some cases it will).

Things unsuccessfully:

  • Initialization of the dictionary and stack with capacity.
  • Listing int for listing to avoid casting.
  • , . !

:

  • hashcode : Hashcodes x + y * parent.Width. , .
  • mquander Technique: . GetGroupMquander.
  • : HashSets, Contains Add. Contains Add , , , , Contains . if (RetVal.Add(s)) curStack.Push(s);

    public static List<Square> GetGroup(int match, Model grid, Square leader)
    {
        Stack<Square> curStack = new Stack<Square>();
        Dictionary<Square, bool> Retval = new Dictionary<Square, bool>();
        curStack.Push(leader);
        while (curStack.Count != 0)
        {
            Square curItem = curStack.Pop();
            if (Retval.ContainsKey(curItem)) continue;
            Retval.Add(curItem, true);
            foreach (Square s in curItem.Neighbors)
            {
                if (0 != ((int)(s.RoomType) & match))
                {
                    curStack.Push(s);
                }
            }
        }
        return new List<Square>(Retval.Keys);
    }
    

=====

    public static List<Square> GetGroupMquander(int match, Model grid, Square leader)
    {
        Stack<Square> curStack = new Stack<Square>();
        Dictionary<Square, bool> Retval = new Dictionary<Square, bool>();
        Retval.Add(leader, true);
        curStack.Push(leader);
        while (curStack.Count != 0)
        {
            Square curItem = curStack.Pop();

            foreach (Square s in curItem.Neighbors)
            {
                if (0 != ((int)(s.RoomType) & match))
                {
                    if (!Retval.ContainsKey(s))
                    {
                        curStack.Push(s);
                        Retval.Add(curItem, true);
                    }
                }
            }
        }
        return new List<Square>(Retval.Keys);
    }
+3
2

, leader . ?

, Square GetHashCode, .

, -.,.

, , , . , , 100 , , :

Dictionary<Square, bool> Retval = new Dictionary<Square, bool>(100);

. : , .

, , , . grid_size , , .

, , , , . , - , . , , , .

if (0 != ((int)(s.RoomType) & match))
{
    if (!Retval.ContainsKey(curItem))
        curStack.Push(s);
}

. . , # , , JIT. , enum match:

RoomEnumType matchType = (RoomEnumType)match;

:

if (0 != (s.RoomType & matchType))

, .

: -, , , , , - . , , , , , , . , , , false. List , true.

    public static List<Square> GetGroup(int match, Model grid, Square leader)
    {
        Stack<Square> curStack = new Stack<Square>(); 
        Dictionary<Square, bool> Retval = new Dictionary<Square, bool>(); 
        curStack.Push(leader);
        Retval.Add(leader, true);
        int numMatch = 1;
        while (curStack.Count != 0)
        {
            Square curItem = curStack.Pop(); 
            foreach (Square s in curItem.Neighbors) 
            {
                if (Retval.ContainsKey(curItem))
                    continue;
                if (0 != ((int)(s.RoomType) & match))
                {
                    curStack.Push(s);
                    Retval.Add(s, true);
                    ++numMatch;
                }
                else
                {
                    Retval.Add(s, false);
                }
            }
        }
        // LINQ makes this easier, but since you're using .NET 2.0...
        List<Square> matches = new List<Square>(numMatch);
        foreach (KeyValuePair<Square, bool> kvp in Retval)
        {
            if (kvp.Value == true)
            {
                matches.Add(kvp.Key);
            }
        }
        return matches;
    }
+5

-

.NET 3.5, RetVal HashSet <Square> < Square, bool > , ( ) . .

, IEnumerable, HashSet. ( ToList() , ).

, -

, , . , , leader + 1y, , + 1y , BACK ( ), , . .

:


foreach (Square s in curItem.Neighbors)
{
    if ((0 != ((int)(s.RoomType) & match)) && (!Retval.ContainsKey(s)))
    {
        curStack.Push(s);
    }
}

, , , , .

0

Source: https://habr.com/ru/post/1705651/


All Articles