Вот некоторые идеи, основанные на моем опыте с проводным протоколом, подобным протокольным буферам.
даты и времени (секунды точность)
даты и времени (миллисекунды точность)
Я думаю, что ответ на эти два будет то же самое, вы бы просто обычно иметь дело с меньшим диапазоном чисел в случае точности секунд.
Используйте sint64/sfixed64, чтобы сохранить смещение в секундах/миллисекундах от известной эпохи, такой как полночь GMT 1/1/1970. Это как объекты Date - internally represented in Java. Я уверен, что есть аналоги в Python и C++.
Если вам нужна информация о часовом поясе, пройдите мимо вашей даты/времени с точки зрения UTC и смоделируйте соответствующий часовой пояс как отдельное поле строки. Для этого вы можете использовать идентификаторы из Olson Zoneinfo database, так как это стало стандартным.
Таким образом, у вас есть каноническое представление даты/времени, но вы также можете локализовать любой часовой пояс.
десятичные с фиксированной точностью
Моей первой мыслью использовать строку аналогично тому, как строится Десятичные объекты из десятичного пакета Python. Я полагаю, что это может быть неэффективным относительно некоторого численного представления.
В зависимости от того, с какой областью вы работаете, могут быть лучшие решения. Например, если вы моделируете денежное значение, возможно, вам удастся с помощью uint32/64 передать значение в центах, а не дробные долларовые суммы.
Есть также некоторые полезные предложения в this thread.
десятичными с переменной точностью
Не протокол Буфера уже поддерживают это с плавающей точкой/двойными скалярными типами? Возможно, я неправильно понял этот пункт.
В любом случае, если вам нужно обойти эти скалярные типы, вы можете кодировать с использованием IEEE-754 в uint32 или uint64 (float vs double соответственно). Например, Java allows you to extract the IEEE-754 representation и vice versa из объектов Float/Double. Существуют аналогичные механизмы в C++/Python.
много значений BOOL (если у вас есть много из них, похоже, вы будете иметь 1-2 байт накладных расходов для каждого из них из-за тегах.
Если вы беспокоиться о потраченных впустую байтах на проводе, вы можете использовать , чтобы сжать многие булевы в один uint32 или uint64.
Поскольку в протокольных буферах нет поддержки первого класса, все эти методы требуют небольшого количества " договор между агентами , Возможно, использование соглашения об именах в ваших полях, таких как «_dttm» или «_mask», помогло бы обмениваться данными, когда определенное поле имеет дополнительную семантику кодирования выше и выше по умолчанию для протокольных буферов.