сжатие строк статическим словарем

Это будет немного абстрактный вопрос, так как я даже не знаю, есть ли какие-нибудь подобные разработки.

Учитывая, что у нас есть приложение, которое пытается доставить текстовые данные из точки A в точку B. A и B находятся довольно далеко, поэтому размер данных оказывает значительное влияние на все важные метрики, которые мы хотим оптимизировать (скорость, задержка и пропускная способность). Первое, что приходит на ум, - это сжатие, но сжатие не так эффективно, когда нам нужно сжать много маленьких сообщений, но очень эффективно, когда размер сжатых данных значителен.

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

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

Решение, которое я ищу, выглядит примерно так: когда алгоритм сжатия пересекает набор данных, он, вероятно, имеет какой-то словарь вещей, которые, как он знает, можно оптимизировать. Этот словарь отбрасывается каждый раз, когда мы заканчиваем сжатие, и всегда отправляется с сообщением в B.

rawMsg -> [dictionary|compressedPayload] -> send to B

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

rawMsg -> compress(existingDictrionaryOfSomeVersion, rawMsg) -> [dictionaryVersion|compressedPayload] -> send to B

теперь очевидно, что здесь предполагается, что B также сохранит экземпляр словаря и продолжит его обновлять, когда появится более новая версия.

Обратите внимание, что именно это уже происходит с такими протоколами, как protobuf или fix (в финансовых приложениях). С любым сообщением у вас есть схема (словарь), и она доступна на обоих концах, а затем вы просто отправляете необработанные двоичные данные, эффективно и быстро, но ваша схема фиксированная и неизменная.

Я ищу что-то, что можно использовать для текста в произвольной форме.

Есть ли какая-нибудь технология, позволяющая это сделать (без фиксированной схемы)?


person vach    schedule 12.04.2018    source источник
comment
Поскольку вы просите порекомендовать библиотеку, я думаю, что ваш вопрос может быть лучше на сайте рекомендаций по программному обеспечению: softwarerecs.stackexchange.com Лично я не знаю ни одной технологии, которая делает именно то, что вы просите. Возможно, лучше всего разработать программное обеспечение гибко (шаблон стратегии), чтобы фактическое сжатие было хорошо изолировано и могло быть легко отключено.   -  person markspace    schedule 12.04.2018
comment
сжатие с помощью gzip, если требуется меньший размер передачи, однако, если требуется передача больших данных, лучше использовать другой поток и передавать паром   -  person slee    schedule 12.04.2018
comment
@markspace он спроектирован таким образом, мне не нужно ничего подключать, но результаты для gzip того не стоят, особенно для небольших сообщений ... и, поскольку это текст в произвольной форме, я не могу просто придумать какое-то сообщение protobuf. ..   -  person vach    schedule 12.04.2018
comment
вы пробовали мгновенно? Сжатие не такое хорошее, но очень быстрое. Может, тебе стоит попробовать ...   -  person fps    schedule 12.04.2018
comment
@slee забудьте о потоковой передаче и общей оптимизации сцены, я думаю, что сделал это хорошо, на данный момент у меня есть выделенный поток, закрепленный на определенном ядре, и он может обрабатывать сообщения (сериализовать и сжимать их) быстрее, чем они приходят, мое узкое место это сеть, и я не могу просто создать несколько подключений, мне нужно, чтобы порядок был таким же ... короче, мне нужно значительно уменьшить полезные нагрузки без пакетной обработки ...   -  person vach    schedule 12.04.2018
comment
@FedericoPeraltaSchaffner не использовал его, но если он имеет потоковый режим и достаточно умен, чтобы динамически улучшать сжатие с использованием ранее наблюдаемых сообщений, тогда это отличный вариант ... он это делает? или каждое сообщение начинается с пустой страницы?   -  person vach    schedule 12.04.2018
comment
У меня есть сообщения, которые иногда являются точными дубликатами или обернуты другими сообщениями ...   -  person vach    schedule 12.04.2018


Ответы (1)


Вы можете просто отправить множество небольших сообщений в одном сжатом потоке. Тогда они смогут воспользоваться предыдущей историей небольших сообщений. С помощью zlib вы можете очистить каждое сообщение, что позволит избежать ожидания создания целого блока перед передачей. Это ухудшит сжатие, но не настолько сильно, как попытка сжать каждую строку по отдельности (что, скорее всего, приведет к их расширению). В случае zlib ваш словарь - это всегда последние 32 КБ сообщений, которые вы отправили.

person Mark Adler    schedule 13.04.2018
comment
так он всегда передает словарь, даже если ничего не изменилось? - person vach; 14.04.2018
comment
Отдельного словаря для отправки нет. Словарь - это просто последние 32 КБ несжатых данных. - person Mark Adler; 15.04.2018