lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On Sun, Nov 1, 2020 at 6:53 PM Coda Highland <chighland@gmail.com> wrote:
On Thu, Oct 29, 2020 at 3:48 PM Sam Putman <atmanistan@gmail.com> wrote:
Is it in fact the case that variadic functions have additional overhead? That is,  calling `fn(a, b, c)` would be cheaper if this was defined as `function fn(a, b, c)`, rather than `function fn(...)` ?

You can reason about this if you think about it. Lua isn't a statically-typed language, and there's no mechanism for dispatching functions differently based on their parameter lists because the bytecode compiler doesn't even know what the function is at compile time. ALL functions are called by pushing the arguments onto the stack, so the invocation part of a variadic function call and a non-variadic function call should have the same performance.

On function startup, a non-variadic function actually has one point that could be more expensive than a variadic call: the non-variadic function will have to make sure that at least the minimum number of stack slots are filled, so it'll have to push nils if you didn't pass enough in. Of course a variadic function can have non-... arguments so it would have to do the same thing for those.

Lua function parameters are names assigned to stack slots. Since variadic parameters don't have names, you can only access their values by using a function (that is, select()). This is the primary source of overhead when working with variadic functions. If you're just passing them through, there's a small overhead involved in looping over the stack slots to copy them instead of copying a number of slots predetermined at compile time -- this is the O(n) thing that people have been talking about. That said, since there's no instruction dispatch necessary for this loop, it's a lot tighter than anything you could have implemented in Lua code itself, although it would still be more overhead than passing through a single table argument.

As Roberto said, you can benchmark it for yourself if you really want to know exactly how much of a difference there is.

/s/ Adam

Thank you Adam. There is of course no substitute for profiling, I asked more to provoke conversation from those more knowledgeable about the internals than I.

"Variadic functions are slower than named parameters" was just a bit of lore I absorbed by osmosis, somewhere along the line. As it happens, I only have LuaJIT and Lua 5.2 running on my own system, and for the purposes of this list, 5.4 would be the useful benchmark, so I won't bother in this case. It's pretty clear that I can just use them when appropriate, and *maybe* revisit that if I ever spot one in a hot loop I'm optimizing.

Cheers,
-Sam