资料摘自<Lua程序设计(第二版)>
字符串缓冲
假设正在编写一段关于字符串的代码,例如正在逐行地读取一个文件。典型的读取代码是这样的:
local buff=""
for line in io.lines() do
buff=buff..line.."\n"
end
上面代码看似可以正常工作,但如果面对较大的文件时,它却会导致极大的性能开销。例如,用这段代码来读取一个350kb大小的文件就需要将近1分钟的时间。
为什么会这样呢?
假设每行有20个字节,读了2500行,那么buff现在就是一个50kb大小的字符串。当Lua作字符串连接buff..line.."\n"时,就创建了一个长50020字节的字符串,并从buff中复制了50000字节到这个新字符串。这样,对于后面的每一行,Lua都需要移动50kb甚至更多的内存。在读取了100行(仅2kb)以后,Lua就已经移动了至少5mb的内存。此外,这个算法还具有二次复杂度。最后,当Lua完成了350kb的读取后,它已至少移动了50gb的数据。
在Lua中,使用table来解决上面这个问题:
local t = {}
for line in io.lines() do
t[#t+1] = line.."\n"
end
local s = table.concat(t)
或
for line in io.lines() do
t[#t+1] = line
end
t[#t+1] = "" --空字符串
local s = table.concat(t,"\n")