Faster Lua VM: Studio beta

When I do tests like these I generally get fluctuating results even without the VM, should I be aware of significant differences otherwise?

There can be a variety of reasons that impact how fast code runs, unless your code is obviously slower in the New VM; there is nothing to worry about.

1 Like

Thank you, I’ll be testing this when I get home.

Run the program multiple times so that it runs for at least 2 seconds. Many things outside of the code in question can cause slowdowns such as physics, instance loading and property changes, also add a 5 second wait before each benchmark.

Thank you, makes much more sense to have a clean slate. But I don’t think instance spawning should affect the code in general? Those are separate threads am I wrong?

Separate virtual threads running on a single system thread. It basically yields one thread while executing another.

Please is there any way you could answer this @zeuxcg?

It depends. We currently don’t do any inter-module analysis so you may get some performance wins if you merge local functions and locals, but if you just put two module tables along the lines of what you’re suggesting then there’s not going to be any difference. If modules are mostly independent there’s not really any point to merging for either reason.

1 Like

Will table.insert and table.remove be more optimized? I currently use tbl[#tbl + 1] and tbl[pos] = nil to add and remove values. Sorry if I’m asking too much.

I think a ton of people (including me) use this type of removing but like it always had been, it can create empty values in a table if not used correctly.

This would make a table not only a mess but can create headaches down the line if your storing a bunch of values at once.

You should always substitute each removed value with another one so that one, it never goes unused, and two, it’ll save space.

The VM should help with this, but realistically the difference shouldn’t Ben noticeable unless your adding and removing from a table like 500 times per minute.

Is it possible for us to manually enable the VM via studio and apply to the game itself?

I have a number of games that could use the extra speed but I have no idea if they’re eligible for it.

Would be nice, thanks!

You can test the vm in studio by being in the beta program and enabling it under the beta features.
Currently you cannot apply it to your game. The staff has to do it manually by changing the fflag.

2 Likes

There’s one thing I noticed that changed in the new VM, which was the complete destruction of the performance of next. I’m not sure why you wouldn’t optimize both, or even just next, since pairs only serves one use, which is iterating through a table, but next can be used to iterate through a table like pairs, but also can be used outside of that.

Take for example this code, which uses pairs for iterating, but I am stuck with next to see if the loop continues, which is inconsistent and slower.

To me, it just makes no sense, why optimize one but not the other? I get you’re optimizing for idiomatic code, but that doesn’t mean you should leave some things slower than others just because they don’t match your code style guide or whatever. Some people like next because of consistency (like me) reasons like this. It’s just annoying because I’m going to have to back and change any cases of this being done with much uglier code than just doing next would do. It just feels really, really lopsided and I don’t really think it should be done this way. If I was to choose, I’d just keep pairs unoptimized, since it is just a one trick pony.

/rant over

2 Likes

Because pairs is translated into VM instructions that don’t call an iterator function on every cycle. It’s said that they might do the same with next if many people ask, but it’s far at the botom of their to-do list.

1 Like

We’ve been over this earlier in the thread. next actually isn’t slower. It’s just as fast as any other function. Don’t confuse pairs being fast with next being slow.

6 Likes

When you say there isn’t any inter-module analysis does that mean, relating to getfenv/setfenv, optimizations are only disabled on the script or module which contains the call to getfenv/setfenv? If a such a module requires another module, is that second module effected even if it doesn’t contain getfenv/setfenv?

If a script uses getfenv on a function received from a module, will that function have optimizations disabled?

Consider the following module:

return function()
    setfenv(2, {ok = 1})
end

Any script that requires this is potentially unsafe to optimize, and not only that but that script can then pass the function around to who knows where and suddenly everything becomes much harder to reliably optimize.

Now I don’t work for Roblox, but my guess would be the effect would be global, or at least heavily propagated in some way.

1 Like

Note, in a version that will ship next week, loops with next (e.g. for k,v in next, table) and loops with localized ipairs/pairs (e.g. local pairs = pairs) will also benefit from the loop iteration optimization.

Standalone calls to next are not specialized in any way for now, this may or may not happen as part of upcoming builtin function call improvements.

9 Likes

@zeuxcg If we could get precise details on this, that would be great

getfenv/setfenv dynamically deoptimizes some optimizations applied to scripts based on the argument.

For example, if you retrieve the env. table of a function declared in a ModuleScript via getfenv, any functions in that ModuleScript will be deoptimized.

As a general rule of thumb, the deoptimization will be applied to functions that share the same environment table. So if you get/set the env. table in a script, only functions from that script will be affected.

5 Likes