[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Re[2]: Still cryptic OOP syntax
- From: David Olofson <david@...>
- Date: Mon, 31 Jan 2005 07:02:37 +0100
On Monday 31 January 2005 06.12, skaller wrote:
[...]
> > At least, EEL calls C and EEL functions the same way,
>
> Yes, but Lua does not. More precisely it has to lookup
> the function by name at some point, and the function,
> if defined in C, has to have the Lua C function interface.
EEL only looks up functions by name when calling through typeless
object references. OTOH, that could mean most of the time, depending
on your programming style. :-)
BTW, I'm working on an enum type that allows "recasting" values across
enums. With some optimizations, using that for indexing stuff won't
cost more than indexing with an integer most of the time, and at most
a table lookup to recast when you happen to get the right name from
the wrong enum.
> > To install a bytecode operator, on would just set the bytecode
> > function pointer to it, and then point the C function pointer to a
> > function that performs a VM call instead of actually performing an
> > operation. No performance penalty for native implementations!
>
> You're missing the point though. Even if a C function were
> called, it is unlikely to be as efficient as the current
> Lua bytecode interpreter adding Number + Number because that
> case is specially treated:
>
> case OP_ADD: {
> TObject *rb = RKB(i);
> TObject *rc = RKC(i);
((GETARG_B(i) < MAXSTACK) ? RB(i) : k+GETARG_B(i)-MAXSTACK)
((GETARG_C(i) < MAXSTACK) ? RC(i) : k+GETARG_C(i)-MAXSTACK)
2 conditional branches
(Which the EEL VM doesn't have BTW. The obvious side effect is that it
needs more opcodes, but those are handled by the main instruction
decode switch() which cannot be avoided anyway. Bad news is I might
hit cache limits on some archs if I take that approach too far...)
> if (ttisnumber(rb) && ttisnumber(rc)) {
(ttype(rb) == LUA_TNUMBER) && (ttype(rc) == LUA_TNUMBER)
2 conditional branches
> setnvalue(ra, nvalue(rb) + nvalue(rc));
> }
> else
> Arith(L, ra, rb, rc, TM_ADD);
> break;
> }
>
> Arith() is messy, it calls another function which tries
> metamethods. But for a native Number type the code involves
> two types checks and this line:
>
> setnvalue(ra, nvalue(rb) + nvalue(rc));
>
> which is basically a native C level + operation.
>
> The point being that without some care of the implementation
> details, a more general system might degrade performance
> of 'the usual case' significantly which probably isn't acceptable.
Yeah... Can't have everything. :-)
However, my point is that even with inline special cases like those in
Lua, and those I used to have in EEL, still involve some conditionals
- and those waste large numbers of cycles very frequently.
It should also be noted that VM instruction decoding burns a major
part of the cycles when doing simple operations like this, so +/-50%
on the actual operation isn't going to impact overall performance all
that much.
Of course, speed can't hurt, but there *are* other languages that are
more appropriate than Lua or EEL or any other VM based solution when
every cycle matters. ;-)
Anyway, they way the EEL operator subsystem is structured now, it
shouldn't be too hard (some cut'n'paste work, mostly) to convert it
to use a [type][operator][type] array instead of the current switch()
+ messy metamethod logic. Would be interesting to see what kind of
impact that would have on performance.
//David Olofson - Programmer, Composer, Open Source Advocate
.- Audiality -----------------------------------------------.
| Free/Open Source audio engine for games and multimedia. |
| MIDI, modular synthesis, real time effects, scripting,... |
`-----------------------------------> http://audiality.org -'
--- http://olofson.net --- http://www.reologica.se ---