整体思路
- 声明一个全局缓存表,这个表中存储table中每个key对应的一个整数索引(是唯一的)
- 当pairs遍历表table1时,先声明一个新的表newtable,然后按数组形式把表table1中的key插入到新table中
- 然后根据table1的key获取全局缓存表中的整数索引,用table.sort根据这个整数索引进行排序整个表
- 如果table1的key在全局缓存表中不存在整数索引,则在全局缓存表最后添加这个key的索引(为保证索引唯一,还需一个全局变量记录当前记录到的索引值是多少,这个变量每次变化都是+1)
最后,此方案就是用空间换了部分时间,如果t的key只有数字和字符串,很适合用这个方案。
代码
local g_cache_index = 1 --记录当前全局缓存表下一次新增key时的key对应的索引
local g_cache_index_tbl = {}
local function Cmp(x,y)
local newx = g_cache_index_tbl[x]
local newy = g_cache_index_tbl[y]
if not newx then --如果x在全局缓存表中不存在索引,则新增这个key的索引
g_cache_index_tbl[x] = g_cache_index
g_cache_index = g_cache_index + 1
end
if not newy then --如果y在全局缓存表中不存在索引,则新增这个key的索引
g_cache_index_tbl[y] = g_cache_index
g_cache_index = g_cache_index + 1
end
return g_cache_index_tbl[x] < g_cache_index_tbl[y]
end
function wwpairs(t)
local a = {}
local j = 1
for n in pairs(t) do
a[j] = n --以数组形式保存t的每个key
j = j + 1
end
table.sort(a, Cmp)
local i = 0
return function()
i = i + 1
return a[i], t[a[i]]
end
end
性能测试
用了这种性能损耗还是比较大的,最好控制下table中key的数量。
我是在游戏中用了lua,不过table的key数量都比较少,在50个以下,还可以接受。
- 用的lua5.1版本测试的,测试代码如下:
function calculateTime(func)
local startTime = os.clock()
-- 在这里执行你要计时的代码
func()
local endTime = os.clock()
local elapsed = endTime - startTime
print("函数执行耗时:" .. elapsed .. " 秒\n")
return elapsed
end
local tbl = {}
for i =0,1000 do
tbl[i] = tostring(i)
end
tbl[-1] = 'start'
for i =0,500 do
tbl['user'..tostring(i)] = 'str'..tostring(i)
end
calculateTime(function()
print('测试wwpairs:')
for i= 1, 1000 do
for k,v in wwpairs(tbl) do
-- print('wwpairs', k,v)
local t = v
end
end
end)
calculateTime(function()
print('测试pairs:')
for i=1, 1000 do
for k,v in pairs(tbl) do
-- print('pairs', k,v)
local t = v
end
end
end)
- 第一次测试:
- 第二次测试