Эффективно получать доступ и перебирать непримитивные массивы с помощью плоских буферов? - PullRequest
1 голос
/ 27 мая 2020

Я работаю над передачей данных облака точек по сети с помощью Flatbuffers в приложение, построенное на Unity.

Скажем, у меня есть следующий файл схемы:

namespace PCFrame;

struct Vec3 {
    x: float;
    y: float;
    z: float;
}

struct RGB {
    R: ubyte;
    G: ubyte;
    B: ubyte;
}

struct PCPoint {
    Position: Vec3;
    Color: RGB;
}

table PCFrame {
    FrameNo: uint;
    Points: [PCPoint];
}

file_identifier "FBPC";

root_type PCFrame;

Я успешно сериализовал и передал буфер. Но после получения ByteBuffer в C# и десериализации его как объекта PCFrame единственный способ получить доступ к точке в массиве Points - это вызвать метод Points(n). Это крайне неэффективно, особенно когда массив может включать сотни тысяч точек, и мне нужно перебирать все из них.

Есть ли способ более эффективного доступа к массиву?

Изменить: В конце концов я отказался от более удобочитаемой структуры PCPoint и вместо этого создал данные Points в виде массива с плавающей запятой (в виде x1, y1, z1, r1, g1, b1, x2, y2 ...) . Таким образом, гораздо более простая схема теперь выглядит так:

namespace PCFrame;

table PCFrame 
{
    FrameNo: uint;
    Points: [float];  // x1, y1, z1, r1, g1, b1, x2, y2, z2, r2, g2, b2, x3, ...
}

file_identifier "FBPC";

root_type PCFrame;

Использование массива примитивного типа позволяет мне извлекать массив байтов напрямую, используя:

ArraySegment<byte> pointsArraySegment = fb_frame.GetPointsBytes();
byte[] pointsByteArray = pointsArraySegment.Value.Array;

Что, в свою очередь, позволяет мне в Buffer.Block: скопируйте весь массив обратно в массив с плавающей запятой сразу:

int offset = pointsArraySegment.Value.Offset;
float[] pointsArray = new float[(pointsByteArray.Length - offset) / sizeof(double)];
Buffer.BlockCopy(pointsByteArray, offset, pointsArray, 0, pointsByteArray.Length - offset);

Доступ к данным точки из массива с плавающей запятой таким способом намного эффективнее. Я до сих пор не уверен, почему FlatBuffers не позволяет делать это с непримитивными массивами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...