原生Lua中的高效可变字节数组

mar*_*256 10 compression lua

我试图在本机Lua中有效地实现LZ77解码器(即没有C库,并且不依赖于非核心Lua库) - 请参阅liblzg.

对于加载和解析二进制文件,Lua字符串工作正常,性能良好(例如使用s:byte(k)方法).但是,为了创建解码的输出数据,字符串不是非常优化,因为它们是不可变的,并且当输出变大时,字符串连接往往需要花费大量的时间.

解码器必须能够:

  • 一次向输出附加一个字节(最多数百万次)
  • 从输出缓冲区读取(或多或少的随机访问)

什么是最好的选择?输出数据的大小是预先知道的,因此可以预先分配.

lhf*_*lhf 11

避免字符串连接:将输出字符串保存到表中并在结尾处写入其中的所有字符串.如果您担心桌子太大,请定期冲洗.见http://www.lua.org/pil/11.6.html


dau*_*tor 9

听起来像table.concat 输出的完美工作只是一个字节表.

当您需要复制时,您可以按照通常的方式进行复制.例如:

for i=#output-5,9 do output[#output+1]=output[i] end
Run Code Online (Sandbox Code Playgroud)

当您最终完成输出流时,将其转换为带有的字符串 str=table.concat(output)

  • 大表的性能损失是多少?我想它实际上是一个数字表(即双精度数),所以只是值大小为8:1,然后是表索引开销. - 我会测试一下.另外,我会从预分配输出表中获得任何东西(因为大小已知)? (2认同)
  • 作品!(速度:3 MB/s,与 C 版本的 300 MB/s 相比,OK)我还通过在单独的变量中跟踪输出长度而不是执行 #output(这是一个成本高昂的操作)来提高速度表)。虽然不确定内存消耗,但我认为:问题已解决。 (2认同)
  • table.concat非常有效; 它实际上是你可以在lua中做到的最有效的连接.将#output保存在另一个变量中也是一种很好的做法(尽管它可能会使事情略微不可读) (2认同)