Luau Native Code Generation Preview [Studio Beta]

Don’t really have a proper benchmarking solution.

When enabling native code for my Conways Game of Life (Purely tables and a lot of for looping), I get around 1.4x - 2x (Could be higher) faster generation steps compared to native code disabled. For some reason the varying 1.4x and 2x is due to the number of live cells being check in every iteration. It seems like native code gets a bigger benefit when there are more live cells being checked.

native code disabled:
image

native code enabled:
image

I’ll try this on my Path Tracer if this makes a significant difference.

3 Likes

i have wave generation (and calculation) in one of my games, is that a valid use case for “native code”?

Not yet but yeah the plan is to use SIMD instructions for Vector3 ops.

8 Likes

Supporting C would be more cool, but I think this is a really surprising and interesting challenge.

but I have a question. Does it download source code from the server into the client and compile it on the client side? In detail, when is it compiled to native code?

1 Like

Supporting a low-level, memory-unsafe, beginner-unfriendly language would be a pretty bad idea.

  • Roblox already has a programming language they’ve built up over the years called Luau. Adding another supported language would not only massively increase the engineering time needed, but introduce extra complexity and confusion among developers
  • C is not memory safe, and there would be a significant amount of time needed to properly sandbox it and fix security vulnerabilities
  • C is literally lower-level than the language the Roblox engine is written in (C++)
  • C isn’t very beginner friendly and is way more complicated to write code in as a beginner than Luau
  • Why would you want to make it more difficult to write code??
5 Likes

The reason for releasing native code is to compile it into machine language, similar to C, so that complex and numerous calculations can be processed more quickly. “Doing complex and numerous calculations faster” There is nothing better than C. Moreover, some Lua functions actually work in C level (like math, string etc). And security only needs to prevent a few libraries and a few security vulnerabilities. If roblox support C, it would be able to quickly perform AI deep learning, pathfinder, and other large operations faster than Lua native code.

1 Like

To add on, people who manage to learn and use C on Roblox would have to go through the tedious effort of allocating and deallocating memory in their code should it be necessary. C doesn’t have a garbage collector to automatically allocate unused memory, so it leaves it up to the user to manually allocate memory from one value to another.

In my experience with C, I find this very tedious.

Will code that involves C → Luau → C transitions see noticeable performance gains when run natively?

1 Like

Luau → C transitions may get a little faster, but C → Luau transitions don’t, so overall not much has changed here and avoiding these transitions is still good for performance, native code or not.

2 Likes

As of Studio 0.593, this beta is now supported on macOS! Reminder:

  • If you’re using an Intel based Mac, make sure you have macOS 10.14 (Mojave) or later;
  • If you’re using an Apple Silicon based Mac, make sure you have macOS 13 (Ventura) or later; additionally, make sure you are running the ARM binary (Activity Monitor should say “Apple”).

We are continuing to work on improvements to native code performance; as these are motivated by specific benchmarks, please continue to let us know if you have code where you are not seeing the expected improvements. We also may reach out to people who posted about their results to discuss them in more detail.

3 Likes

Does this provide little to no benefit when getfenv is used within the script?
I tried this out on a script that is very complex and can be performance heavy, and I saw no speedup at all.

I really need as much speed out of this script as I can get and this would really help but I’m not seeing any benefit. Little of the script uses Vector3s or CFrames.

Using getfenv is very important for this script to function as intended as it seems to be most reliable way to see what script a function is being called from. (In a module)
The next best thing I could do is search the string returned by debug.traceback, and it seems like a bad idea, but I might have to so I can get this optimization.

Does getfenv really disable the optimizations though, or am I reading this wrong?

1 Like

Yes, getfenv will often lead to native code, as well as many other optimizations, getting disabled. You should use debug.info instead – we advise against the use of getfenv or setfenv.

2 Likes

The issue with debug.info is that it only returns a string with the location of the script, not the actual instance. This leads to me having to search the string which is something I want to avoid doing.

Is there any other way?
I really want to avoid having to read a string to find the script calling the function, rather than getfenv where I can get the instance directly.

This is the main reason I still use getfenv, but I might try this method if it’s the best alternative there is.

1 Like

We don’t currently have a way to get the script instance (and we don’t have planned API extensions that would let you do that).

2 Likes

Is there a future where scalar code receives SIMD optimizations or will it be exclusive to vectors?

It would be weird to use vectors for a lot of code, especially if you have to e.g. perform bitwise ops, so I’m curious.

2 Likes

We don’t currently plan to implement automatic vectorization of scalar code.

Importantly though, a lot of scalar code can run fairly well without this. The reason why we’re going to use SIMD for Vector3 is because it’s convenient, and the reason why Vector3 math is slower right now in native codegen than we’d like is not because it doesn’t use SIMD, but because it’s not integrated into native code at all so you pay for some fallback code to run every time a math or indexing operation is performed.

4 Likes

This is awesome! I’m interested to see how much faster code could be when it’s run as native code.

I do wonder, once this feature is released to live games, how does native code relate to developer analytics’ error reporting system? Will we be able to see errors in Studio or Analytics that are generated from native-code scripts?

Viewing errors from games that our players played really helps me to find bugs I’d never find otherwise. I’m hesitant to make my code native if I lose the ability to track in-game bugs.

3 Likes

There’s no conflict here - as mentioned in OP, we fully support the entire language along with all APIs, which includes the error handling behavior. Deviation between native and non-native code behavior is considered a bug and if these come up in the future we intend to fix them. This includes behavior that isn’t fully specified by the language/documentation.

5 Likes

I’ve just tested this on an NES emulator I made.
It went from about 256 ms per frame to 64 ms per frame, and I’m not even testing this on a high end pc!

3 Likes

I tested it with my data manager script.
Without native code generation, it took 47 ms.
With native code genertation, it took 4 ms.

This is amazing.

Screenshots:

Screenshot 2023-09-24 140606

Screenshot 2023-09-24 140947

7 Likes