В чем разница между массивом и ArrayBuffer?

Мне просто интересно, почему все используют ArrayBuffer вместо обычных array, string или строковых JSON для отправки сообщений с сервера клиенту. Это более эффективно?

Кроме того, просто интересно, что такое Uint8Array, чем он отличается, где их использовать и т. д.

В настоящее время я использую Node.js с Socket.io, но я рад перейти на чистый WebSockets, если это лучший подход.


person Luke    schedule 18.04.2016    source источник
comment
следуйте этому- developer.mozilla.org/en-US/docs/Web /JavaScript/Typed_arrays   -  person Khairul Islam    schedule 19.04.2016
comment
Отправка каких сообщений?   -  person Bergi    schedule 19.04.2016


Ответы (1)


ArrayBuffer — это больше, чем просто массив . Он содержит необработанные двоичные данные. Это очень полезно для прямого управления памятью и экономии места.

Когда вы создаете обычный массив, во многих случаях вы не получите надлежащего набора непрерывной памяти, поскольку массивы могут содержать любую комбинацию различных типов объектов. Это полезно, когда у вас есть динамические данные и несколько типов вместе (часто случается в JS), но не так полезно, когда вы знаете точное распределение памяти, которое вам нужно.

Это также позволяет просматривать данные на уровне байтов. Например, в двоичных форматах данных довольно часто используется номер идентификатора длиной n байт, поле длиной m байт, указывающее, сколько байтов используется для этого поля, и m' байт данных, фактически составляющих поле данных.

[ identifier ][ bytes of data ][ data ]

С ArrayBuffer у вас есть возможность перемещаться по этим данным на уровне байтов, используя различные представления. Обычный массив не позволяет вам перемещаться по данным с таким уровнем детализации, потому что нет никаких гарантий относительно расположения памяти.

Наконец, поскольку вы сообщаете компилятору/интерпретатору точно, сколько места вы собираетесь использовать и точно как вы собираетесь его просматривать, он может делать гораздо больше. расширенные оптимизации при работе с этими данными. При повторении этих данных ему не нужно совершать расчетные скачки по памяти. Вместо этого он точно знает, как далеко нужно продвинуться вперед в памяти, чтобы найти следующую точку данных.

Что касается Uint8Array, это типизированный множество. По сути, он сообщает компилятору/интерпретатору, что вы будете обращаться к этим данным исключительно как к 8-битным uint, что, опять же, позволяет улучшить оптимизацию. Затем вы можете использовать для него стандартную индексацию массива (arr[0], arr[1], etc.), и вы получите эквивалентные значения uint из массива.

TL;DR Они занимают меньше места, когда известен точный формат данных, позволяют более точно перемещаться по вашим данным и предоставляют компилятору/интерпретатору больше возможностей для оптимизации.

person Mike Cluck    schedule 18.04.2016
comment
Отличный ответ! Например, как в MMO отправлять обновления игрокам с помощью Buffer/ArrayBuffer? - person Luke; 19.04.2016
comment
@Mirabilis Все зависит от того, как вы его отправляете. Вот документы socket.io о том, как отправлять бинарные данные. Вот один вопрос, показывающий, как обрабатывать его через WebSockets. - person Mike Cluck; 19.04.2016
comment
Хорошо, скажем, у меня есть массив игроков, которых я хочу отправить своим клиентам с моего сервера: [{id:1,x:5,y:10},{id:2,x:15,y:20},{id:3,x:25,y:30}]. Но клиент не знал бы длину массива, так что я мог бы иметь что-то вроде этого: [length(3),id,x,y,id,x,y,id,x,y] так `[3,1,5,10,2,15,20,3,25,30]? Помощь! ;) - person Luke; 19.04.2016
comment
They take less space when the exact data format is known -› Они имеют в виду массивы, верно? - person akki; 28.05.2020
comment
@akki Они относятся к ArrayBuffer и любому TypedArray - person Mike Cluck; 29.05.2020