Luau Recap: November 2019

As an aside to anyone who is interested, map is included in the rodash library, along with loads of other utilities to support functional programming constructs.

https://codekingdomsteam.github.io/rodash/api/Tables/#map

It’s not blazing fast, and shouldn’t be used in performance sensitive code, but it helps develop clean code which in most cases is what you’ll want to be writing.

1 Like

table.foreach is pretty much what you’re asking for. I believe it’s deprecated due to the stuff mentioned above.

@zeuxcg I’ll make sure to get my code to you sometime soon. It’s also a bit messy since it’s kind of a prototype of my algorithm so I may comment it for you if it helps out with testing.

1 Like

There are so many game-changing things in this post - thanks for investing the time into this.

“On Windows and Xbox, we’ve tuned our interpreter to be ~5-6% faster on Lua-intensive code”

Are there any changes to the performance of mobile devices? Particularly the lower-end devices.

1 Like

Most of the updates improve performance across the board; this one was highlighted in particular because it was specific to the compiler we use on Windows/Xbox builds. We didn’t do any additional mobile-specific tuning yet, although of course the Luau release itself improved the script execution performance noticeably on mobile devices as well (more so on Android than on iOS due to the hardware differences). I don’t think we have up-to-date numbers on this (performance got better), but here are numbers from April this year from an early unreleased version of Luau:

iOS, iPhone6
Lua time / Luau time 04/12
TerrainGenerator 1.61
N-Body 1.74
Life 1.74
Android, Pixel1
Lua time/Luau time 04/12
TerrainGenerator 1.64
N-Body 2.68
Life 3.12
Factorial 2.86
4 Likes

Excited to see these changes in action, especially with some of those table functions! Great job :slight_smile:

2 Likes

Excellent, thanks for clarifying

1 Like

I try to use typeof over type in all cases on Roblox, yes. The only time I wouldn’t is if I were trying to filter out userdata specifically because it’s easier to write type(x) ~= "userdata" than it is to write it using typeof.

I don’t have any great examples for using typeof a bunch since in cases where I’d have to, I cache the result to avoid calling it a bunch. That being said, I do have some code that with some slight modification would result in typeof getting called a bunch. It’s a function to convert data types to a string containing a constructor for them that I used in an old plugin. If I removed the caching for the result of typeof it could reasonably be used as a benchmark I think.

I’ll clean it up and send it to you later today if you’re interested.

1 Like

If anyone’s curious about this:

7 Likes

To my understanding, using locals to reference variables in a default environment gives direct access to said variables. If I was to localize needed variables, then modify the Lua environment, would previously localized variables still be optimized or impacted by deoptimization?

1 Like

touching on table.create(), is it recommend to switch all table creation functions and whatnot to this new format for performance, or is the change not that big (i.e: not a huge game-changer for lag, etc)?

1 Like

It depends. Generally, if you’re not sure why/if table.create would help you, it won’t though; a lot of games and developers won’t have a use for it.

2 Likes

Alright, thanks for the clarification.
I did not know that those table functions were run in C, interesting to know :).

1 Like

I just encountered a correctness error:

for i = 0.05, 0, -0.05 do print("A", i) end
for i = 0, 1 do print("B", i) end

print("========")

for i = 0.05, 0, -0.05 do print("A", i) end for i = 0, 1 do print("B", i) end

Observe that the two sets of loops do the same thing, with the only difference being a newline. When ran within Play Solo or Run, the following output is produced:

A 0.05
A 0
B 0
B 1
========
A 0.05
A 0
B nil
6 Likes

Is that with or without beta enrollment?

1 Like

No beta enrollment. The behavior does not occur unless Play Solo or Run is active.

It would be helpful to know exactly what compiler code is running with. Like a companion to the _VERSION variable to tell what version of Luau is being used, or if it’s being used at all.

3 Likes

Quick question; as far as I know, Luau already optimises references library functions (like math.floor) so you don’t have to do stuff like local floor = math.floor, but would it optimise calls to string library functions written like these?

-- Method 1
print(("hello %s"):format("world"))

-- Method 2
local foo = "hello %s"
print(foo:format("world"))

-- Method 3
local function foo(bar)
    print(bar:format("world"))
end
foo("hello %s")

-- Method 4
local tbl = {}
tbl.foo = "hello %s"

print(tbl.foo:format("world"))

1 Like

Yeah so this is a transpiler bug. We fixed this last week so it should be released this week or next week - don’t remember when the cutoff happened. This is because, when we run in vanilla VM, we parse the source with Luau and then generate Lua code (to support new syntax extensions), and this process had a bug that manifested based on space-based alignment.

The vanilla VM is going to disappear completely in a few weeks time hopefully, so _VERSION wouldn’t have long-term value.

5 Likes

I have one further question about table.create. Does this have any performance benefits for string keys? For example, calling table.create(100) and assigning 100 string keys. If so, should I be using table.create(length) wherever a max table length is known?

Edit: Also for @zeuxcg and testing as well as anyone who’s generally interested here’s the algorithm including some basic tests to measure performance/compression efficiency: Bit-Slice CompressionAlgorithm.rbxm (2.9 KB)

I wrote it about a year ago and I haven’t edited it all that much so it’s a bit messy and could use some work (hence why I’m working on a newer version).

I can explain my algorithm via DMs if someone wants to know how it works since I designed it from scratch. (Note it can inflate data size up to ~40% based on my testing if the data set is heavily random)

1 Like

table.create only preallocates the array portion of the table - using it on a table that will only use string keys is a bad idea (wastes memory & performance).

3 Likes

Quick question; since there’s optimisations being made for speed, are there also similar optimisations being made for memory usage so that game scripts and the Lua objects they create take up less space in RAM?

2 Likes