Как стать автором
Обновить

Комментарии 39

Есть еще не плохой protobuf от google
Протобуф требует схему описания данных, а тут нет. И это было одним из требований.
При всех своих достоинствах это достаточно тяжеловесное решение, объем генерированных классов (например, Java) довольно громоздкий + либа весом 666667 байт, в малоресурсных системах вроде j2me практически неприменимо несмотря даже на наличие портов.
Интересно.
Надо было им для сравнения компактности еще добавить ASN.1 PER.
НЛО прилетело и опубликовало эту надпись здесь
Устранение Фатального Недостатка?
Очень даже интересно, исследую как раз Google Protocol Buffer, но все преимущества этого мне как раз очень даже. Дело за малым — кроссбарузерная клиентская реализация (как ProtoBuff.js) и библиотеки для РНР и Node.JS
… множество других (правда, бегло поискав на github, я пока не нашёл реализации на JavaScript...).


здесь есть и JavaScript.
О, действительно. Спасибо.
Правда там указано, что
The Java and JavaScript versions are translations from the C# version

Наверняка кто-нибудь решит сделать с нуля в «натуральном» виде.
Я так понял что если я хочу закодировать огромный массив одинаковых вещей, то перед каждым элементом будет префикс, что не есть гуд.
Всё нормально. Если вы хотите хранить кучу строк — вам же всё равно длину строк надо знать. Для мелких строк размер будет кодироваться прямо в том-же байте, что и префикс. Если кучу мелких чисел — они тоже будут влезать в этот 1 байт. Числа покрупнее будут занимать уже чуть больше байт, но всё равно скорее всего лучше чем оригиналы. Конечно не хаффман но тоже неплохо.
Хотя если вы храните толпу char-ов в районе ~240 — использовать на это по два байта конечно не прикольно…
Байтовые строки же.
Это общая беда всех кодировщиков. На любую схему кодирования найдётся другая, которая на некоторых данных будет лучше.

Если хочется оптимальнее положить какой-то блок, можно использовать байтовую строку, и парсить её более оптимально, не протоколом контейнера.

upd: опередили ))
Более того, уже есть расширение, которое позволят кодировать повторяющиеся строки ссылками. Это позволяет получить ещё более компактное представление, если у вас огромный массив одинаковых объектов:

  [
     {
       "name" : "Cocktail",
       "count" : 417,
       "rank" : 4
     },
     {
       "rank" : 4,
       "count" : 312,
       "name" : "Bath"
     },
     {
       "count" : 691,
       "name" : "Food",
       "rank" : 4
     }
  ]


Начиная со второго объекта, ключи кодируются как ссылки на строки и занимают 3 байта.
Самый простой пример, передать буфер вершин (килобайты флоатов). Аккурат такая задача была, смотрел различные форматы, почти везде такая же схема как и в этом примере. В итоге остановился на RIFF контейнере.
Дурововский TL не имеет такой проблемы, можно сделать большой массив float'ов.

Будет лишь оверхед в 8 байт (4 байта на тип, 4 байта на кол-во элементов).
Спасибо. Но я взял канонический формат RIFF, который настолько простой что любой кто сам захочет написать что то подобное напишет его же. (имя чанка + размер чанка + данные)
А если в табличке сравнить [24, [24, 34]]?
Спасибо за статью, интересный формат данных. Возможно, когда-нибудь воспользуюсь. Но хочу заметить об одном существенном недостатке формата по сравнению, например, с HDF5. Отсутствие произвольного доступа к элементам, отсутствие возможности быстро выяснить, сколько и каких содержится элементов в файле. Такой формат нужно или грузить в память целиком, или обрабатывать в несколько проходов, если он не влезает в память. Также, если нужна не вся информация из файла — все равно придется прочитать его весь.
Разные форматы имеют разные цели. Если нужна метаинформация о количестве элементов, то можно создать своё расширение к CBOR: выбрать свободный номер тега и создать простую структуру из базовых типов, в которой описать всю нужную метаинформацию. Кодировщик после прохода по данным сосчитает число элементов и запишет информацию в теге в конец или начало кодированных данных. Т.о. декодировщик сможет затем извлечь нужную информацию о данных не загружая весь объём данных.
НЛО прилетело и опубликовало эту надпись здесь
Concise Binary Object Representation (сжатое бинарное представление объекта) — формат данных, который был спроектирован таким образом, чтобы обеспечить максимально простой код реализации, формирования компактных выходных данных и возможность расширения формата без необходимости обмена информацией о версии.
1. Потоковый парсер позволит не грузить в память ничего, кроме текущего значения. Потоковый парсер для этого формата возможен.
2. Это же не СУБД и не файловая система, чтобы иметь произвольный доступ к элементам. Произвольный доступ — довольно тяжелое в реализации требование, подтверждением служит многообразие упомянутых систем.
Хорошо. Про текстовые форматы (типа xml и json) знают все, а бинарные к сожалению не так широко известны (я например знал лишь то что они существуют, но ни разу с ними не сталкивался ни как программист, ни как пользователь).
Во всех играх используются повсеместно, DOOM, Quake, половина форматов хранения 3D массива данных, практически все ГИС используют свой кастомный внутренний бинарный фрпмат хранения данных, треки GPS так же могут записываться в бинарном формате, фактически зесь описан именно codec — формат хранения данных для передачи, с последующим его получением и декодированием.
В том-то и дело, что «свой кастомный внутренний бинарный формат хранения данных». Я тоже такой могу придумать и придумывал неоднократно.
А хочется, чтобы был некий универсальный и повсеместно распространенный формат, библиотеки для работы с ним в большинстве языков программирования, софт для просмотра и редактирования этих данных и т.д. Как с XML.
были у меня идеи, когда положительная и отрицательная бесконечность кодируется 0x7F и 0x81, а NAN — 0x80. Но, видимо, до этого еще далеко. Хоть логика учтена.
А зачем? Разве они так часто встречаются, чтобы кодировать их одним байтом?
В NaN есть еще целочисленная диагностическая информация (payload). Изредка она используется.
Чем это принципиально лучше msgpack'а, помимо фатального недостатка?
Msgpack изначально не делал различия между байтовыми строками и текстовыми. Можно вспомнить жаркую дискуссию по этому поводу. С проблемой столкнулись ещё в 2011 году. Основная проблема с изменением была связана с тем, что модификация формата приведёт к потере обратной совместимости, т.е. спецификация затрудняла дальнейшие развитие формата. CBOR предусматривает возможность для развития без потери обратной совместимости.
Второе менее значимое отличие — это поддержка массивов/строк неопределённой длины.
На саму концепцию строк неопределенной длины у меня нет слов. Цензурных.

Ну, JSON, ну ладно. Но двоичный-то формат всегда программа пишет! Уж программе-то размер должен быть известен, раз она память под него выделила! Не понимаю.
программе-то размер должен быть известен, раз она память под него выделила!

Если она из сокета данные читает, откуда ей размер знать? Даже в http Content-Length не всегда указан.
Заранее известный размер всегда предпочтительнее, но он, к сожалению, далеко не всегда доступен энкодеру.
Ну да, ну да. Сначала не делаем Content-length обязательным, а потом жалуемся, что размер неизвестен. А потом и в двоичных форматах.
Посмотрим на тот же хабр: имя юзера сверху, новостные блоки, реклама, комментарии. Длина страницы заранее неизвестна.
Разве что не сразу в сокет её посылать, а сначала в буфер. Но так пользователю дольше ждать. Сейчас статья видна до загрузки комментариев.
Речь про длину строки, а не всего содержимого. Длина имени пользователя, заголовка новости и текста комментария уже известны серверу на момент отправки.

Страницу целиком вполне можно рассматривать как набор кадров потокового вещания, тут я не спорю.
Речь о Content-Length в HTTP
Есть еще из похожего формат сообщений RADIUS & DIAMETER. DIAMETER будет покруче.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории