递归LUA功能中的环和条件优化
The following is the code of my function
function myfunction ( ... )
local tbl = table.pack(...)
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slight modification.')
return
end
end
if some condition then
**recursive call to myfunction**
else
some result
end
end
该功能正常工作,并给我带来了预期的结果。但是,问题可以观察到该功能以递归方式自称。因此,我下面提供的代码的第一部分在每个递归电话中也会重复几次。显然,我只想检查一次输入,如果功能不正确,则退出该函数。如果输入正确,则不应将其检查每个递归调用。因此,如何为此目的对代码进行优化。可以将某些值分配给全局变量,然后在功能内(如果在其他情况下)将其使用以避免重复。但是再次,对值的支票将重复重复(尽管与当前方法相比,它的成本较低。问题是避免重复以下代码(这是上述代码的一部分)。
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slightly modified')
return
end
end
例如,考虑以下功能
function factorial(n)
if (n == 0) then
return 1
else
return n * factorial(n - 1)
end
end
时 。 cattorial(9.3)
被执行到堆栈溢出中,因为添加了以下错误
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * factorialwithinputcheck(n-1)
end
end
机制代码> fortorialWithInputCheck(9.3)未导致堆栈溢出。
The following is the code of my function
function myfunction ( ... )
local tbl = table.pack(...)
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slight modification.')
return
end
end
if some condition then
**recursive call to myfunction**
else
some result
end
end
The function works fine and it gives expected results to me. But the problem as one can observe that function is calling itself in recursive manner. So the first part of the code which I am giving below also gets repeated several times during each recursive call. Obviously I want to check input only once and exit the function if it is incorrect. If input is correct, then it should not be checked every recursive call. So how the code can be optimized for this purpose. Can some value be assigned to global variable and then use it somewhere inside the function (in if else condition) to avoid repetition. But again the check for value will get repeat (though it is less costly compared to the current approach. The problem is to avoid repetition of the following code (which is part of above code).
for _, v in ipairs(tbl) do
if type(v) ~= 'number' then
print('Error: Something different is expected.')
return
elseif v~= math.abs(v) then
print('Error: Your input needs slightly modified')
return
end
end
As an example, consider the following function.
function factorial(n)
if (n == 0) then
return 1
else
return n * factorial(n - 1)
end
end
When factorial(9.3)
is executed it results into stack overflow as no error input check is involved. To handle this the following error mechanism is added.
function factorialwithinputcheck(n)
if type(n) ~= 'number' then
error('only numbers are expected')
return
elseif n~= math.floor(n) or n~=math.abs(n) then
error('only positive integers are expected')
return
end
if (n == 0) then
return 1
else
return n * factorialwithinputcheck(n-1)
end
end
This function gives error and stops execution whenever input is incorrect. The factorialwithinputcheck(9.3)
doesn't result into stack overflow. But again the input check is made in every recursive call. How this code for example can be optimised?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如我的评论中更具体,我建议这样:
或隐藏 _factorial :
但同样,我不完全确定这样 _factorial 函数是否具有多次“创建”(这也会对性能产生影响)。但也许这可以通过一些基准测试来解决。
编辑:哦,如果你想要一些输入清理:到目前为止,你不会检查负数。Edit2:既然你要求对阶乘函数进行一般优化。是的,当然可以将递归过程转换为迭代过程(避免多次创建新的堆栈帧)。
使用某种累加器(
acc
)将n*acc
传递给下一个调用,您也可以使函数尾部递归,(根据到这个pil章节(我希望在更频繁的lua版本中没有变化) lua然后将为您处理这个问题)。例如:(
但说实话,如果我循环阶乘,我并没有看到太多的性能提升(
0.000293
s vs0.000354
s) code> 形式 0 到 40,以21!
开头的数字已经超出了 lua 中数字的范围(对于我的安装),仅使用非常基本的基准进行检查))Being more specific as in my comment, I'd propose something like this:
or hiding
_factorial
:but again, I'm not completely sure if this way the
_factorial
function has to be "created" multiple times (which should have a performance impact as well). But maybe this can be figured out with some benchmarking.EDIT: Oh and if you want some input sanitizing: Up to now, you don't check for negative numbers.Edit2: And since you ask for general optimization of your factorial function. Yes of course one could convert the recursive procedure into an iterative one (avoiding creating new stack frames that many times).
Using some sort of accumulator (
acc
) passingn*acc
down to the next call, you could alternatively make the function tail recursive, (according to this pil chapter (I hope there is no change in that in more frequent lua verions) lua will then handle this for you).For example:
(but to be honest I don't see much of a performance boost with this (
0.000293
s vs0.000354
s if I loop overfactorial
form 0 to 40, numbers starting with21!
are already beyond the range for numbers in lua (for my installation), checked only with a very rudimentary benchmark))