Lua新手:备用(Knuth)伪随机函数性能如何?

我正在为iOS和OSX开发一个Lua的魔幻风格游戏。我对Lua还比较陌生,却发现在我的平台上,math.random 函数并非真正的随机。我已经设置了通过函数产生随机数的调用:

function rollD(max)
   return math.random(max)
end

我在这篇文章中找到了一个非常好的答案,我认为它可以解决我的问题(对于魔幻游戏来说,每次游戏都不同是相当关键的)。但是,为了使以下修改后的函数:

function rollD(max)
    return srandom(seedobj,1,max)
end

起作用,我不得不让来自 Donati 的 Knuth 适应方法的:

local seedobj = { seed = -232343 }

不再是本地的,然后实际上修改为使用 (os.time() * -1)。到目前为止,这确实完美地发挥作用,我的(非常简陋的)魔幻游戏正在完美地生成随机的敌人和地牢。但当事情按计划进行时,我仍有些担忧……

如果大量调用了 srandom(每级别大约会有一千次以上的调用),那么使 seedobj 成为全局变量,我会有一些性能损失吗?我认为,因为它嵌套在表中,所以种子是一个引用,我担心了徒劳。但是,是否有一种方法可以修改此函数,以便我可以更有效地调用它?

点赞
用户2633423
用户2633423

在 Lua 中访问全局变量就像访问表字段一样。如果 seedobj 是全局变量,则以下代码在 Lua 5.2 中等价于:

function rollD(max)
    return srandom(_ENV.seedobj,1,max)
end

在 Lua 5.1 中等价于(大致上):

function rollD(max)
    return srandom(_G.seedobj,1,max)
end

其中 _ENV 是当前环境表的变量,_G 是全局变量的变量。

因此,每次调用 rollD 都会产生一个小的性能损失,因为这是间接访问,比起局部变量,会慢一些。一般来说,这种损失对于 rollD 被调用时执行的其他操作的复杂性影响很大或者很小。

在您的特定情况下,这种损失很难被注意到,因为 srandom 实现已经执行了更多的密集计算(其中包括一些表访问)。

2013-10-19 07:46:24