lua的pairs遍历乱序的一种解决方案(pairs固定遍历顺序)

文章介绍了一种使用全局缓存表优化表排序的方法,通过预先存储键的唯一整数索引来提高效率。然而,该方法对表中键的数量有要求,适用于键为数字和字符串且数量较少的情况。作者还提供了lua代码示例和性能测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整体思路

  1. 声明一个全局缓存表,这个表中存储table中每个key对应的一个整数索引(是唯一的)
  2. 当pairs遍历表table1时,先声明一个新的表newtable,然后按数组形式把表table1中的key插入到新table中
  3. 然后根据table1的key获取全局缓存表中的整数索引,用table.sort根据这个整数索引进行排序整个表
  4. 如果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个以下,还可以接受。

  1. 用的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)
  1. 第一次测试:
    在这里插入图片描述
  2. 第二次测试
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值