2010-11-24 14 views
7

ネイティブLua(すなわち、Cライブラリなし、非コアLuaライブラリへの依存性なし)でLZ77デコーダを効率的に実装しようとしています - liblzgを参照してください。ネイティブLuaの効率的な可変バイト配列

バイナリファイルの読み込みと解析には、Lua文字列が完全に機能し、パフォーマンスが良好です(例:s:byte(k)メソッドを使用)。しかし、デコードされた出力データを作成するためには、文字列は不変であり、文字列の連結には多くの時間を要し、出力が大きくなると非常に時間がかかるので、文字列はあまり最適ではありません。

デコーダができなければならない:

  • 追加時の出力に1バイトの出力バッファから
  • 読む(多かれ少なかれランダムアクセス)(最大数百万回まで)

最適なオプションは何ですか?出力データのサイズは事前に分かっているため、事前に割り当てることができます。

+2

で文字列に変換し、出力ストリームが終わったら?これは教育的なものかサンドボックス化されたLua環境で必要とされるものですか? –

+0

これは教育的なものです(低レベルのコンパイルされた言語と管理されたスクリプト環境の間でパフォーマンスがどのように異なっているかを見たいと思います)。また、純粋なLuaの実装があれば、展開が容易になると思います。 – marcus256

+0

完璧な質問です。 Btw私は同じアイデアを持っていたユニークではない – Hydro

答えて

7

table.concat あなたの出力のための完璧な仕事のような音のバイトだけのテーブルです。

コピーする必要がある場合は、通常はテーブルの場合と同じように行います。 例:

for i=#output-5,9 do output[#output+1]=output[i] end 

あなたが最後になぜあなたはCライブラリを使用することはできません、好奇心からstr=table.concat(output)

+2

大きなテーブルのパフォーマンスのペナルティは何ですか?私はそれが実際には数値のテーブル(つまり倍数)であると仮定します。したがって、値は8:1になり、テーブルインデックスのオーバーヘッドがあります。 - 私はそれをテストします。また、出力テーブルを事前に割り当てることで何かを得ることができますか? – marcus256

+1

好奇心を要しない:table.concatはいかに効率的ですか?つまり、私は1,000,000のテーブル要素を持っています。何らかの再帰的連結(1 + 1,1 + 1,1 + 1、...100 + 100,100 + 100など)、999,997 + 1,999,998 + 1などで終わることはありませんか? – marcus256

+1

WORKS! (速度:3MB/s、Cバージョンでは300MB/sと比較してOK)#outputを実行するのではなく、別の変数で出力の長さを追跡して速度を上げました。テーブル)。しかし、メモリ消費についてはわかりませんが、私はそれを考慮します:問題解決。 – marcus256

10

文字列の連結を避ける:出力文字列をテーブルに保存し、最後にすべての文字列を書き込む。テーブルが大きくなりすぎることが懸念される場合は、それを定期的にフラッシュしてください。 を参照してくださいhttp://www.lua.org/pil/11.6.html

+0

Heh、あなたは私にそれを打つ。代わりにあなたをアップしました。 – Zecc

+0

残念ながら、これはバッファへのランダムアクセスの問題を解決しません。サポートされなければならない操作の1つは、「出力バッファーから5バイトを開始して9バイトを取り出し、出力バッファーに追加する」(たとえば、コピー自体が重複する可能性があります)です。 – marcus256

+0

@ marcus256このような場合でも提案されているアプローチはまだ有効です。文字列テーブル上でこれらの操作を抽象化するためにいくつかの関数を実行する必要があります。おそらく、重複した読み込み/書き込みが発生する必要があるたびに、テーブルを単一の文字列に 'フラッシュする'必要があります。 –

関連する問題