あなたを動かすための提案として。
優れた圧縮率を示すのに十分なサイズのバッファーを使用した投機的な先読みは、変更する価値があります。
これにより、ストリーミングの動作が変更され (出力が発生する前に、より多くのデータを入力する必要があります)、フラッシュなどの操作が大幅に複雑になります。また、圧縮ステークにかなりの余分な負荷がかかります。
一般的なケースでは、新しいブロックを開始できる各ポイントで分岐し、すべてのルートが使用されるまで必要に応じて両方の分岐を繰り返して、最適な出力が生成されるようにすることができます。入れ子の振る舞いをしたパスが勝ちます。これは、新しいブロックをいつ開始するかの選択が非常にオープンであるため、重要な入力サイズでは実行できない可能性があります。
最小 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 の構築が行われる可能性があります。ヒューリスティックが強力な指標であることが判明した場合は、投機的な性質を排除し、何があってもその時点で交換することを決定できます。