2
\$\begingroup\$

I I'm trying to make an multiplayer game using golang and unity. Golang server side checking units on scene(like a character move). It also sends the information (position, health) of the units on the scene to the Unity 20 times per second. a unit contains 15 bytes of information. there is an average of 10 units in a scene. So golang sends Unity a byte array of size 150(10*15) 20 times per second.

my question is to make this byte array meaningful on unity side with the best performance.

private void UdpFrameHandle()
{
    // _recieveData -> packet head(2 byte) + units data(150 byte)
    var pureData = _recieveData.packet.Skip(2).Take(_recieveData.packet.Count()).ToList();

    // find unit count
    var unitCount = pureData.Count() / 15;

    // parse units
    for (int i = 0; i < unitCount; i++)
    {
        var unitInfo = ByteToUnitNetwork(pureData.Skip(15 * i).Take(15).ToList());
        FrameManager.SendDataToView(unitInfo.ViewId, unitInfo);
    }
}

protected UnitNetworkDto ByteToUnitNetwork(List<byte> arr)
{
    var viewId = BitConverter.ToInt16(arr.Take(2).ToArray(), 0);
    float x = BitConverter.ToSingle(arr.Skip(2).Take(4).ToArray(),0);
    float z = BitConverter.ToSingle(arr.Skip(6).Take(4).ToArray(),0);
    int health = BitConverter.ToInt16(arr.Skip(10).Take(2).ToArray(), 0);
    int teamType = arr.Skip(12).Take(1).First();
    int targetViewId = BitConverter.ToInt16(arr.Skip(13).Take(2).ToArray(), 0);

    return new UnitNetworkDto
    {
        ViewId = viewId,
        X = x,
        Z = z,
        Health = health,
        TeamType = teamType,
        TargetViewId = targetViewId
    };
}

this is my code. do you think there is a better way. Or do you have any suggestions?

\$\endgroup\$
1
  • \$\begingroup\$ Did I answer the question? \$\endgroup\$
    – aepot
    Jan 18, 2022 at 22:17

1 Answer 1

0
\$\begingroup\$

First of all, use array instead of list. Every time you know the data size, use array instead of list.

Stop instantiating lot of new arrays, it's very slow. Use offset instead.

This one arr.Skip(12).Take(1).First() looks really killing. Why not arr[13]?

Also Int16 is short not int. Use matching types.

Let's assume that _recieveData.packet is byte[].

private void UdpFrameHandle()
{
    int unitCount = (_recieveData.packet.Length - 2) / 15;
    
    for (int i = 0; i < unitCount; i++)
    {
        var unitInfo = ByteToUnitNetwork(_recieveData.packet, i * 15 + 2);
        FrameManager.SendDataToView(unitInfo.ViewId, unitInfo);
    }
}

protected UnitNetworkDto ByteToUnitNetwork(byte[] arr, int offset)
{
    short viewId = BitConverter.ToInt16(arr, offset);
    float x = BitConverter.ToSingle(arr, offset + 2);
    float z = BitConverter.ToSingle(arr, offset + 6);
    short health = BitConverter.ToInt16(arr, offset + 10);
    byte teamType = arr[13];
    short targetViewId = BitConverter.ToInt16(arr, offset + 14);

    return new UnitNetworkDto
    {
        ViewId = viewId,
        X = x,
        Z = z,
        Health = health,
        TeamType = teamType,
        TargetViewId = targetViewId
    };
}

Also BitConverter isn't safe to use because its numbers format depends on CPU architecture. Check BitConverter.IsLittleEndian before use. If available, use BinaryPrimitives instead.

Also always keep in mind when you're thinking of performance: "Linq is slow".

\$\endgroup\$
4
  • \$\begingroup\$ hi, thanks for your reply. actually this is just a sample code. Of course I'm not using linq. Also, I didn't ignore the IsLittleEndian issue, it just doesn't exist in this code. Finally, I wrote a more advanced version of this system. When I prepare the codes of that system, I will upload them here and update this comment. I would like you to have a look at those codes :) \$\endgroup\$
    – snn
    Jan 31, 2022 at 8:23
  • \$\begingroup\$ slightly more advanced version codereview.stackexchange.com/questions/273568/… \$\endgroup\$
    – snn
    Jan 31, 2022 at 9:07
  • \$\begingroup\$ @sinanc less advanced because you're calling SubArray which is probably wasting memory and CPU time while creating a new array. Use offset in the original array like here. You didn't took everything from this review. In C# 8 syntax like array[2..4] is also possible but it creates a new array too. \$\endgroup\$
    – aepot
    Jan 31, 2022 at 10:21
  • 1
    \$\begingroup\$ I understand. thanks for your feedback \$\endgroup\$
    – snn
    Jan 31, 2022 at 10:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.