Как предложение, чтобы вы пошли.
Спекулятивный взгляд в будущее с буфером достаточного размера, чтобы указание на превосходное сжатие стоило изменений.
Это изменяет поведение потоковой передачи (требуется больше данных для ввода, прежде чем произойдет вывод) и значительно усложняет такие операции, как сброс. Это также значительная дополнительная нагрузка в кольях сжатия.
В общем случае можно было бы гарантировать, что это дало оптимальный результат, просто разветвляя в каждой точке, где можно начать новый блок, принимая обе ветви, повторяющиеся по мере необходимости, пока не будут приняты все маршруты. Путь, в котором было гнездо, побеждает. Это вряд ли будет возможно на нетривиальных входных размерах, так как выбор, когда начинать новый блок, так открыт.
Простое ограничение его как минимум 8K выходными литералами, но предотвращение более 32K литералов в блоке приведет к относительно гибкой основе для попытки спекулятивных алгоритмов. вызвать 8K субблок.
Самый простой из которых (псевдокод):
create empty sub block called definite
create empty sub block called specChange
create empty sub block called specKeep
target = definite
While (incomingData)
{
compress data into target(s)
if (definite.length % SUB_BLOCK_SIZ) == 0)
{
if (targets is definite)
{
targets becomes
specChange assuming new block
specKeep assuming same block as definite
}
else
{
if (compression specChange - OVERHEAD better than specKeep)
{
flush definite as a block.
definite = specChange
specKeep,specChange = empty
// target remains specKeep,specChange as before
but update the meta data associated with specChange to be fresh
}
else
{
definite += specKeep
specKeep,specChange = empty
// again update the block meta data
if (definite is MAX_BLOCK_SIZE)
{
flush definite
target becomes definite
}
}
}
}
}
take best of specChange/specKeep if non empty and append to definite
flush definite.
OVERHEAD - некоторая константа для учета стоимости переключения блоков
Это грубо, и, вероятно, может быть улучшено, но это начало анализа, если ничего больше. Примените код для получения информации о том, что вызывает переключение, используйте его для определения хороших эвристик, которые могут быть полезны для изменения (возможно, что степень сжатия значительно упала).
Это может привести к созданию specChange, выполняемому только тогда, когда эвристика посчитает это разумным. Если эвристика окажется сильным индикатором, вы можете покончить со спекулятивным характером и просто решить поменяться в точке, несмотря ни на что.