lua-users home
lua-l archive

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

If they are constant by design, this is to avoid all dynamic overrides, and then allow suppressing runtime lookups in tables of symbols (we know that those lookups are quite slow: Lua still does not have what the Google V8+ VM for has for _javascript_ (later modified by Google to support its new language for Android that supports also a Java-like VM, Mozilla Rust, and ): prototyped "shadowed" tables containing a cached version of tables, which are readonly, but can be recreated if the table keys are modified, but that are much faster because the cache contains a pre-cached lookup, so that all accesses via these shadowed tables are indexed by integer index only, and JIT itself can also cache the key values in registers.

Tables in Lua are still costly, but most objects we use need tables whose list of keys are most often constant over time. adding a <const> declaration inside a Lua module will instruct the symbols table of the module that some keys are contant and can be cached. These <const> declarations are still not part of the exposed API of the module, they are internal to the module itself, but to make sure they are valid and don't require runtime checks, they ensure that the assigned symbols cannot be removed and will stay at static positions

    it may just happen that some key may receive a nil value, however the binding of this valuer will not drop the symbol, i.e. the entry in the equivalent table, so that dynamic lookups are not longer necessary: Lua already supports this by design in its tables that have two parts: an indexed part and a hashed part. However, the indexed part does not allow any position to be assigned a nil value, so that this creates an assumption if foreach-loops using ipairs(): nil-value checks are not performed when enumerating a table in the indexed part (and there's no nil-check when enumerating with pairs() the hashed part, but such nil check exists in ipairs() to determine when terminating the enumeration).

Lot of costly operation needed for dynamic languages can be optimized using "ghost" tables, notably it allows transforming dynamic typing automatically into static typing, it allows dropping many costly type inferences (frequent in Lua, including in the Lua code itself: ghosting tables would accelerate these by elimination of dead code, when it knows that some tests are always false or true inside the constraint set by the "ghost" table). However it requires developing a stronger JIT compiler in the VM itself, and would make Lua larger and more complex and not suitable for small embedded systems (but today most embedded systems are much more capable than what they were in the past, they have decent processors, often have mulitple cores, and more memory; the only limitation is for embedding Lua in a server-hosted container serving lots of queries, that's were there are limitations in terms of storage space in memory and CPU usage, and where a JIT is generally dropped, such limitation generally does not affect client systems (e.g. mobile hosts, whose own capabilities are now much larger than what a server would allow on a shared service used by lot of clients, possibly millions).

Do we need these <const> declarations ? No if we have a full JIT integrated. But yes to allow a partial JIT support that could save resource: explicit const declaration can hint directly the compiler with only a small price (checking dynamic propertoes to make sure that ghost tables are still valid, and then allow recompilation and caching again of the compiled code). Such strategy works very well inside Python (it just requires storage space for precompiled .pyc modules in a cache).

Do we have some Lua implementations using a JIT (that could like Pythin generate ".luc" precompiled modules instead of just the basic .lua loaders and a runtime only using dynamic lookups and type checks in the application, without any possibility of dead code elimination ? Certainsly with explicit "<const>" declarations a basic JIT could save a lot of code and accelerate Lua, with less lookups in tables, less usage of the memory allocator, less work for the garbage collector (which has a LOT to do in Lua, much more frequently than in _javascript_ or Python: already Lua is very memory intensive, but does not make any use of the external storage for a precompiled code cache, even if it's cheaper than memory and this could increase the performance dramatically: "<const>" declarations are imperative, not dynamic, so they can greatly help a JIT precompiler).

Le dim. 25 avr. 2021 à 05:37, yanfeng peng <> a écrit :
The idea is great, it can speed up the running speed of the code, but this limits the freedom of the code and restricts the modification of variables in the running phase.

云风 Cloud Wu <> 于2021年4月25日周日 上午10:56写道:
The type of constants in Lua can only be boolean, number, string now.
It looks good If it can support more types.

My suggestion is that if it assigns a global var to a const local var,
 the var is evaluated during the loading stage rather than running.

Idioms like :

local print <const> = print

function foobar()
   print "Hello World"

The local print can be a light C function constant. It can reduce the
memory footprint (fewer upvalues) and may faster. And it's more
friendly to the JIT or AOT compiler.