Optimization and debug
View-point
I know CSharp.lua produces readable Lua code from Roslyn, what keeps...
- Output is more identical or familiar to C# sources. "debuggable"...
- Output more re-usable, like a library.
But, some cons:
- Table-indexing can have extra overhead for hash, but string-internalisation makes it less intense. This affects micro-operations, such as namespace qualifying, member indexing, etc..
This is table-indexing.
t['x']
t.x
rawget(t, 'x')
(Raw access and dot or brackets access.)
- Output may take over 40kB, so I won't be able to run it on Transformice.
My suggestions to solve the cons
Lua re-usability is optional, e.g., --reusable
There's no reason to reuse things of the output (e.g., namespaces and names) from Lua. You could rather re-use the csc assemblies, for avoiding re-compilation.
With -reusable flag, table indices aren't avoided.
Member, method, etc.. names and access
A... name
A name like MyStaticDef.StaticMethod or NsQual.Member is rather expressed by using mangled locals.
This means the output names will be something like (except _ENV or _G)
A B C
a b c
_A
_0
__
___A
rather than
Class.StatixMethod
OriginClass.Peek
Nsx.Ver
Mx.CoreClass.Go
-- etc...
... A minimum combination of every allowed Lua id char.
Struct variables
Structs variables are stored as locals in Lua code. If contained in a class or object, they're stored as array fields instead.
Instance variable (class)
Normal variables are stored in contiguous arrays and accessed by indices.
These arrays are class instances theirselves. Since some classes extend another, it may be necessary to reserve the first array field for helping virtual methods or the is operator.
Here an example...
-- first variable, named x
uint x = 10
compiles to...
-- in class constructor
this[1]=10
or may be even removed from the output or expanded to a local.
Inline methods if appropriate.
Lua API access
Things like table.remove or print aren't accessed directly, as they can conflict with mangled names. You rather put
local _ENV = _ENV or _G
_ENV.table.something
And more, add something like Lua namespace for allowing to access the environment table from C#. Do that w/o overhead, e.g.:
namespace Lua
{
public struct LuaValue
{
...
public LuaValue rawget(LuaValue key);
publuc LuaValue index(LuaValue key);
}
}
// later on
LuaValue.Env.index(new LuaValue("print")).call()
This must be optimized such that LuaValue does have no overhead. This means, LuaValue will simply be stored as the expected value. Table, anything...
E.g.:
_ENV.print() -- output
A pull request wouldn't be so hard, err.
Debug flag
Line numbers and columns can be kept in various ways, optionally. Errors will carry them, be caught and display them along w/ the message.
i put readable in the first place, it will be simple and easy optimization. now some class with long namespace already will be local variable,future may optimize more. the code may be
local SystemConsoleWriteLine = System.Console.WriteLine
SystemConsoleWriteLine(1)
consider inheritance of classes, keep the structure of the class is better.
@yanghuan (Issue updated accordingly, from cellphone.)
thans you advice, I've been balancing code size ,performance and readability. Some complex optimization will be more complicated to implement, the workload may be too large.
"use array index instead field string name", i also considered, But I think the gains may be extra inconvenience.
"Structs variables are stored as locals in Lua code." it is a good idea, i also want to do it, It's a little complicated, but I'll try.
"Inline methods if appropriate." maybe i will do a little, the major work is the lua runtime, like luajit.
''Lua API access", like https://github.com/yanghuan/CSharp.lua/issues/19, it is in plan.
I've been trying to control the size of the code, and some of the features that aren't profitable will be discarded.