Крионет: лучшая структура данных?
Я пишу графическую онлайн-программу на Java и использую библиотеку Kryonet для управления сетью.
Я считаю, что эта библиотека требует, чтобы пакеты были экземплярами классов. Я не уверен в этом, однако не нашел никакой документации, предлагающей иное.
Я немного знаком с сетями и эффективностью памяти, но плохо разбираюсь в этой библиотеке и поэтому не уверен, будут ли эффективными стандартные подходы.
Мое лучшее предположение для эффективной структуры данных - разбить мои объекты Vec2 на поплавки, представляющие свойства X и Y соответственно. Логично, что было бы эффективно хранить эти значения в одном массиве с плавающей запятой, а затем передавать его как пакет.
Я не очень знаком с управлением памятью, поскольку оно относится к объектно-ориентированному программированию. Поскольку этот "пакет" технически является экземпляром, я предполагаю, что это сделает "расположение памяти" более похожим на "структуру C". Кроме того, я понятия не имею, как Kryonet обрабатывает данные, так что все это очень теоретически.
У меня такой вопрос: будет ли объединение всех данных в один массив с плавающей точкой более эффективным, чем, скажем, размещение всех свойств как отдельных членов класса? Или, возможно, наборы массивов, а не только один?
Заранее спасибо.
1 ответ
Нет смысла манипулировать вашими полями в массиве: массив не даст вам ничего с точки зрения эффективности пространства или времени. Большим исключением являются текстовые представления, такие как JSON, которые должны включать имена "полей" вместе с их значениями. Я имею в виду двоичные представления, где структура данных, о которых идет речь, известна всем сторонам. Исходя из моего очень быстрого взгляда на Kryonet, похоже, что представление, по сути, является двоичным.
В качестве примера представим объект со схемой, похожей на:
{
x: 5.483,
y: 0.7245
}
Этот объект имеет два поля с плавающей точкой. Двоичное представление может быть ровно 8 байтов - четыре байта для каждого числа с плавающей запятой. Это предполагает, что все стороны знают, что пакет состоит из двух чисел с плавающей запятой. Кроме того, вы можете аннотировать двоичное представление с типами. Эти первые версии могут выглядеть примерно так:
0000000 af40 bc74 393f d578
0000008
С другой стороны, текстовое представление может быть чем-то вроде JSON:
{"x":5.483,"y":0.7245}
Это представление имеет переменный размер в зависимости от точного значения (не связанного с величиной) рассматриваемых чисел. Сравните это с кодированием в виде массива в JSON:
[5.483,0.7245]
Это всегда будет меньше, чем вариант объекта, но не обязательно короче, чем двоичное представление. Более того, в отличие от бинарного представления, текстовое представление имеет переменный размер, который должен быть либо включен (с префиксом длины), либо помечен (например, нулевым символом).
Что касается скорости сети, это зависит от того, что именно вы делаете и как вы определяете скорость. Можно сказать, что скорость - это скорость, с которой вы можете передавать много данных в байтах / секунду. Можно также сказать, что скорость - это количество времени, которое требуется одному пакету для достижения пункта назначения. Другим показателем является время прохождения сигнала туда и обратно (RTT), которое обычно (но не всегда) примерно вдвое больше, чем за один рейс в любом направлении между двумя программами.
Если вы пытаетесь максимизировать скорость передачи данных / времени, вам нужно, чтобы данные занимали меньше места - чтобы их представление было меньшим. Если вы пытаетесь минимизировать время между точками, то же самое происходит, но с одной важной оговоркой: сетевые протоколы, такие как TCP, обычно реализуют алгоритм Nagle, который будет ожидать отправки данных в течение короткого периода времени и отправки нескольких небольших пакетов вместе. (это уменьшает перегрузку сети и может быть отключено).