Nanopb один из требований к размеру

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

Моя цель — передавать элементы данных с устройства на устройство, каждый элемент данных имеет 32-битный идентификатор и значение. Значение может быть любым, от 1 символа до длинной строки. Мне интересно, что было бы наиболее эффективным способом объявления сообщений для этого типа проблемы.

Я думал примерно так:

message data_msg{
    message data_item{
        int32 id = 1;
        oneof value{
            int8  ival = 2;
            float fval = 3;
            string sval = 4;
        }
    }
  repeated data_item;
}

Но, как я понял, это преобразуется в объединение C, которое соответствует размеру самого большого элемента. Скажем, я ограничиваю строку до 50 символов, тогда объединение всегда имеет длину 50 байт, даже если мне потребуется 4 байта для числа с плавающей запятой.

Я правильно понял это или есть какой-то другой способ сделать это?

Спасибо!

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
1
0
561
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Если размер в памяти является проблемой, есть несколько доступных вариантов. По умолчанию выделяется максимально возможный необходимый размер, что упрощает управление памятью. Если вы хотите динамически выделять только необходимый объем памяти, вам придется решить, как вы хотите это сделать:

  1. Используя опцию компиляции PB_ENABLE_MALLOC, вы можете использовать тип поля FT_POINTER для строки и других больших полей. Затем память будет выделена с помощью malloc() из системной кучи.

  2. С FT_CALLBACK вместо выделения какой-либо памяти вы получите обратный вызов, в котором вы можете прочитать строку и обработать или сохранить ее любым удобным для вас способом. Например, если вы хотите записать строку на SD-карту, вы можете сделать это, даже не сохраняя ее полностью в памяти.

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

Как насчет того, чтобы использовать только кучу необязательных полей вместо одного? Я предполагаю, что после сериализации это не будет иметь значения, но в памяти будет несколько ненужных нулевых указателей для каждого элемента данных, занимающего место, верно?

Ou Tsei 23.05.2019 09:06

@OuTsei По умолчанию необязательные поля также непосредственно выделяются в структуре. Если они настроены указатели (тип = FT_POINTER), это означает, что память выделяется отдельно, как описано в этом ответе.

jpa 23.05.2019 09:48

Так что, может быть, вместо этого иметь отдельную спецификацию data_item для всех типов данных (float, int string и т. д.) и иметь повторяющуюся структуру для всех отдельно?

Ou Tsei 23.05.2019 12:10

@OuTsei И где вы собираетесь взять память для этой повторяющейся структуры, если ее размер непостоянен? Это всегда будет заканчиваться либо статическим выделением максимального размера, либо динамическим выделением. Вы можете структурировать динамическое размещение разными способами, но это не изменит его основных свойств, таких как более сложное тестирование.

jpa 23.05.2019 19:36

Другие вопросы по теме