Data serialization-deserialization tool. Allows you to prepare data for transfer/storage in the internal IndexBuffers format with minimal overhead and a convenient API. Supports tool generation for C++.
- Principle of use
- Benefits and features
- Schema format
- Description of API of the generated source code (TODO)
- Description of IndexBuffers internal data format (TODO)
- Comparison with alternatives
↑ Principle of use
- Writing a
*.ibs
text file with a data scheme. - Generating of source code by using the IndexBuffers compiler.
- Inclusion and use of the generated source code in your project.
↑ Benefits and features
- The most simple and intuitive API of the generated code.
- Minimum of source code - one per schema, without external dependencies other than STL.
- Minimum of memory allocations - you can use previously allocated memory or use
the only internal buffer based on
std::vector
for the packet. - Zero memory overhead if all fields are fixed.
- Packages are ready for use at any time after the call
create
orfrom
. - Native C-like schema description language.
- Support for optional fields, namespaces, constants, enums, structs, unions.
- Schemes must be UTF-8 encoded.
- Alignment is not currently implemented, but you can manually arrange the schema's fields in the desired order.
- Converting Little-Endian <> Big-Endian is not currently implemented.
↑ Schema format
IndexBuffers schema language supports:
- specifying of namespaces
- inclusion of other schema files
- enums with specific values, as well as the use of enums parameters as constants (min, max, count)
- constants of different formats (bin, dec, hex, float, scientific float)
- structs with regular fields, optional fields, fixed and variable length arrays, default values
- unions for storing one of the fields in one cell
The detailed description of the schema format you can see here (TODO).
IndexBuffers schema example:
//File: "cheat_sheet.ibs"
include "additional.ibs" // Has namespace AdditionalNS
namespace ExtNS::IntNS
enum Color: uint8 {
RED // 0
GREEN = 3 // 3
BLUE // 4
}
struct ScalarTypes: uint8 {
int8 a
uint16 b
optional int32 c
optional uint64 d
float32 e
float64 f
}
struct Vec3f: no_header
{
float32 x = 0 // When specifying a default value, "optional" is not allowed
float32 y = 0
float32 z = 0
}
const uint32 fixedSize = 16 // Atomic types only, including enum
struct Arrays: uint16 {
optional uint8 f[16] // Fixed size array
bytes b[fixedSize] // Fixed size array of bytes
// Dynamic size arrays are always "optional"
int16 m[] // Dynamic size array of integers
Vec3f v[]: uint8 // Dynamic size array of structs
}
union Variant: uint8 {
Color color // Inside "union", "optional" and a default value are not allowed
Arrays data
int64 arr[]
}
struct AnotherOne {
bytes string[]
optional Variant variant
Color colorChannels[Color.count] // Also exists ".min", ".max"
Color colorMask = Color::BLUE
AdditionalNS::SomeType someData // From "additional.ibs"
}
↑ Comparison with alternatives
Tool | Time1, mcs | % | Time2, mcs | % | Size of packet, B | Size of code, KB |
---|---|---|---|---|---|---|
Protocol Buffers v2 | 1.411 | 215 | 43.979 | 328 | 106 | external + 96.4 |
Protocol Buffers v2 lite | 1.407 | 214 | 37.225 | 278 | 106 | external + 85.8 |
Protocol Buffers v3 | 1.527 | 233 | 42.778 | 319 | 106 | external + 90.6 |
Protocol Buffers v3 lite | 1.527 | 233 | 42.611 | 318 | 106 | external + 90.6 |
FlatBuffers | 0.656 | 100 | 13.379 | 100 | 296 | external + 19.8 |
Cap'n Proto | 1.084 | 165 | 151 | external + 52.0 | ||
IndexBuffers | 0.523 | 80 | 15.621 | 116 | (uint8) 104 | 45.5 |
IndexBuffers | 0.517 | 79 | 15.586 | 116 | (uint16) 132 | 45.5 |
IndexBuffers | 0.512 | 783 | 14.617 | 109 | (uint32) 188 | 45.54 |
- Time for one serialization+deserialization, Zen 3 "Vermeer", 4.5 GHz.
- Time for one serialization+deserialization, i.MX6 armv7l, 1 GHz.
- To make IndexBuffers more faster, need to work out the issue of aligning the fields.
- Unlike alternative tools, the generated IndexBuffers code has no dependencies
on either additional tool header files or additional static tool libraries
(like Protocol Buffers and Cap'n Proto).
Инструмент сериализации-десериализации данных. Позволяет подготавливать данные для передачи/хранения во внутреннем формате IndexBuffers с минимальными накладными расходами и удобным программным интерфейсом. Поддерживается генерация инструмента под C++.
- Принцип использования
- Преимущества и характеристики
- Формат описания схемы данных
- Описание API сгенерированного кода (TODO)
- Описание внутреннего формата данных IndexBuffers (TODO)
- Сравнение с альтернативными инструментами
↑ Принцип использования
- Написание текстового файла
*.ibs
со схемой данных. - Генерирование исходного кода с помощью компилятора IndexBuffers.
- Включение и использование сгенерированного исходного кода в своём проекте.
↑ Преимущества и характеристики
- Максимально простой и интуитивно понятный API сгенерированного кода.
- Минимум файлов с кодом - по одному на схему, без внешних зависимостей кроме STL.
- Минимум выделений памяти - можно использовать заренее выделенную память или
использовать единственный для пакета внутренний буфер на
std::vector
. - Нулевые накладные расходы по памяти, если все поля фиксированные.
- Пакеты готовы к использованию в любой момент после вызова
create
илиfrom
. - Собственный C-подобный язык описания схемы.
- Поддержка опциональных полей, пространств имён, констант, перечислений, структур, объединений.
- Схемы данных должны иметь кодировку UTF-8.
- Выравнивание на данный момент не реализовано, но можно вручную располагать поля в нужном порядке.
- Конвертация Little-Endian <> Big-Endian на данный момент не реализована.
↑ Формат описания схемы данных
Язык описания схемы данных IndexBuffers поддерживает:
- указание пространств имён
- включение других файлов со схемами данных
- перечисления с указанием специфических значений, а также использование параметров перечисления в качестве констант (min, max, count)
- константы разных форматов (bin, dec, hex, float, scientific float)
- структуры с обычными полями, опциональными полями, массивами фиксированной и переменной длины, значениями по-умолчанию
- объединения для хранения одного из вариантов полей в одной ячейке
Подробное описания формата схемы данных можно увидеть здесь (TODO).
Пример описания схемы данных IndexBuffers:
//File: "cheat_sheet.ibs"
include "additional.ibs" // Имеет namespace AdditionalNS
namespace ExtNS::IntNS
enum Color: uint8 {
RED // 0
GREEN = 3 // 3
BLUE // 4
}
struct ScalarTypes: uint8 {
int8 a
uint16 b
optional int32 c
optional uint64 d
float32 e
float64 f
}
struct Vec3f: no_header
{
float32 x = 0 // При указании значения по-умолчанию, "optional" запрещён
float32 y = 0
float32 z = 0
}
const uint32 fixedSize = 16 // Только атомарные типы, включая enum
struct Arrays: uint16 {
optional uint8 f[16] // Массив фиксированного размера
bytes b[fixedSize] // Массив байт фиксированного размера
// Массивы динамического размера всегда являются "optional"
int16 m[] // Массив целых чисел динамического размера
Vec3f v[]: uint8 // Массив структур динамического размера
}
union Variant: uint8 {
Color color // Внутри "union", "optional" и значение по-умолчанию запрещены
Arrays data
int64 arr[]
}
struct AnotherOne {
bytes string[]
optional Variant variant
Color colorChannels[Color.count] // Также есть ".min", ".max"
Color colorMask = Color::BLUE
AdditionalNS::SomeType someData // Из файла "additional.ibs"
}
↑ Сравнение с альтернативными инструментами
Инструмент | Время1, мкс | % | Время2, мкс | % | Размер пакета, б | Размер кода, Кб |
---|---|---|---|---|---|---|
Protocol Buffers v2 | 1.411 | 215 | 43.979 | 328 | 106 | внешний + 96.4 |
Protocol Buffers v2 lite | 1.407 | 214 | 37.225 | 278 | 106 | внешний + 85.8 |
Protocol Buffers v3 | 1.527 | 233 | 42.778 | 319 | 106 | внешний + 90.6 |
Protocol Buffers v3 lite | 1.527 | 233 | 42.611 | 318 | 106 | внешний + 90.6 |
FlatBuffers | 0.656 | 100 | 13.379 | 100 | 296 | внешний + 19.8 |
Cap'n Proto | 1.084 | 165 | 151 | внешний + 52.0 | ||
IndexBuffers | 0.523 | 80 | 15.621 | 116 | (uint8) 104 | 45.5 |
IndexBuffers | 0.517 | 79 | 15.586 | 116 | (uint16) 132 | 45.5 |
IndexBuffers | 0.512 | 783 | 14.617 | 109 | (uint32) 188 | 45.54 |
- Время на одну сериализацию+десериализацию, Zen 3 "Vermeer", 4.5 ГГц.
- Время на одну сериализацию+десериализацию, i.MX6 armv7l, 1 ГГц.
- Чтобы сделать IndexBuffers ещё быстрее, нужно проработать вопрос
выравнивания полей. - В отличии от альтернативных инструментов, у сгенерированного кода
IndexBuffers нет зависимостей ни от дополнительных заголовочных
файлов инструмента, ни от дополнительных статических библиотек
инстумента (как у Protocol Buffers и Cap'n Proto).