lua-users home
lua-l archive

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


On 2023-05-05 17:09, Jorge Visca wrote:
And another alternative, with optional out parameter:

  m.add = function ( a, b, out )
    if out then
      out.n = a.n + b.n
      return out -- for concatenating calls
    else
      return m.new{ n=a.n+b.n }
    end
  end

The optional output variant can look rather assembly-like, and I've used it repeatedly in the past. I'd say don't worry about the `if`, especially if you care enough about speed that you fall back to LuaJIT (which will generally just get rid of that entirely.)

My style of writing these tends to be

  m.add = function( a, b,   c )
    if not c then  c = m.new( )  end
    -- now just assume that c exists
    c.n = a.n + b.n
    return c
  end

(otherwise you'll duplicate the "real" code in both branches…) If I *must* know data about the content for the constructor, I'll use a separate `local` function that does the main computations and then passes the results in a shape that I can pass to the ctor, in which case the duplication is avoided again. (In that case I also tend to have an `update` or `set` function, that takes args like the ctor and just reuses an existing value.)

End result is that I can either use the functions in a "don't care about low-level efficiency stuff" way…

  function foo( a, b )
    local c = (a + b) + a
    return c + c
  end

…or in a precise way that avoids allocations wherever possible and looks a bit weird & verbose like asm:

  function foo( a, b,   c )
    if not c then  c = m.new( )  end
    local d = tmp( m ) -- if it's worth keeping a cache of temp variables by type, else just m.new( )
    m.add( a, b,   c )
    m.add( c, a,   d )
    m.add( d, d,   c )
    release( d ) -- return to the cache, if you forget it just gets GC'd eventually
    return c
  end

(and LuaJIT can turn that into _crazy_ fast code! I once wrote a fairly simple ray-tracer in Lua/JIT and meticulously recycled coordinates/vectors/colors, and in the end it was faster than the C version. A good part of that's probably attributable to the C version having more features, but it's still a good example for LuaJIT being able to optimize this really really well.)

-- nobody

[code is unchecked, just written directly in the mail client… but hopefully correct enough to get the ideas across]