i have this gigantic script
it (along with it’s modules) are the only scripts in the game and they all have the native tag
i have met all the requirements shown in original post, and strict typechecking told me there was no type errors
How does it work with module scripts? I tried it on my Particles Collisions Module but i see no difference in performance. Should i put -!native in ModuleScript or Script? Or maybe in both?
Very useful feature indeed. Faster computing were exactly what I’ve been waiting for on Roblox!
--!native
local TimeBegin = os.clock(); --> Benchmarking.
local Primes = {2, 3};
local function isPrime(x: number)
for Index: number = 1, #Primes do
if x % Primes[Index] == 0 then
return false;
end
end
Primes[#Primes + 1] = x;
return true;
end
local function Calculate_nth_Prime(n: number)
local i = 5;
repeat
isPrime(i);
i += 1;
until #Primes > n
return Primes[n];
end
local Prime = Calculate_nth_Prime(25000); --> Calculating the 25000th prime number!
print(
("Prime number is %d operation took %.5fs"):format(Prime, os.clock() - TimeBegin)
);
Here are the results I’ve got from my budget CPU:
Native Output: Prime number is 287117 operation took 4.85615s
Default Output: Prime number is 287117 operation took 9.24579s
Luau code calculating 25000th prime number gets about 2X faster with native code execution!
From what I understand from this post; certain sections of our code, specifically those that do not rely on tables, Lua C functions, and the Roblox Engine, are compiled into a low-level assembly-like code for computation.
A really cool new feature. From my testing the compiler likes buffers a lot it makes it a lot more quicker when I use buffers instead of vectors and variables with some expections.
There could be more features that allow you to tell the compiler what to expect I can’t wait to use this with the new editable mesh/images
Do you know why relying on tables will not make native Lua as effective? Is it because tables are already executed in roughly the same C code, regardless of whether or not you have native Lua enabled? Thanks.
I don’t think this was mentioned in this post, but apparently the native code generation does not work in the command line using loadstring, but it does work when in Run mode on the server:
Is it still using loadstring when in run mode, or is the module required instead? Using loadstring in general disables a lot of Luau optimizations. It makes sense that it also won’t benefit from native compilation.
neither. It’s a server script which runs right after entering Run mode (by pressing Test > Run). But you’re right that --!native does not work for scripts that loadstring was used on.
Hello. I have noticed a very huge problem when --!native is enabled. Namely, writing to a buffer a region whose end “touches” the buffer’s end will cause a slow down of TWO times for some reason, and if that region does not touch the end, it runs the function at regular speed. This happens regardless of whether i8, u8, i16, u16, i32, u32, f32, or f64 is used (I’m referring to the buffer.writeXXX functions):
--!native
local function time(func, label)
local t1 = os.clock();
func();
local timeDif = os.clock() - t1;
warn(if (label ~= nil) then `{label}: {timeDif}` else timeDif);
return timeDif;
end
local length = 10_000_000;
------------------------------------------------------------------------------
--// Buffer assignment (touches end of currentI buffer)
local bytesPerElement = 4;
local size = length * bytesPerElement;
local allBytes = buffer.create(size);
local currentI = buffer.create(13 + bytesPerElement); -- extra 1 is *not* added
time(function()
for i = 0, size - 1, bytesPerElement do
buffer.writeu32(currentI, 13, buffer.readu32(allBytes, i));
end
end, "native A")
------------------------------------------------------------------------------
--// Buffer assignment (does not touch end of currentI buffer)
local bytesPerElement = 4;
local size = length * bytesPerElement;
local allBytes = buffer.create(size);
local currentI = buffer.create(13 + bytesPerElement + 1); -- extra 1 is added
time(function()
for i = 0, size - 1, bytesPerElement do
buffer.writeu32(currentI, 13, buffer.readu32(allBytes, i));
end
end, "native B")
------------------------------------------------------------------------------
--// Normal assignment
local allBytes = table.create(length, 0);
local currentI = 0;
time(function()
for i = 1, length do
currentI = allBytes[i];
end
end, "native C")
As you can see, native A’s for loop takes 0.08817541666212492 seconds (~ twice as slow as native B), native B’s for loop takes 0.039451791657484137 seconds, and native C’s for loop takes 0.03687004165840335 seconds.
Actually, this seems to very likely be an Apple-silicon problem. I tested this on my old Intel 2018 13" MacBook Pro with Intel Iris Plus Graphics 655 and 8 GB of RAM, and like you, there was no difference between A and B.
How am I just knowing about this now! This is so cool! So basically luau is the same as the native script beside native script having faster times and luau supporting more devices? Are there any other differences?
Weird issue where when I do some specific stuff my buffer variable holds a different variable.
I really don’t understand what’s causing it.
--!native
local Buffer = buffer.create(1);
buffer.writeu8(Buffer, 0, 0); --// We need to write to the buffer or else it doesnt work
local Var1;
local Var2 = "Hello, World!";
--[[
having "Var1" and "Var2" above causes the "Buffer" variable to hold "Var2" value.
]]
local function Bug()
--// If done right (what is even the right way) our "Buffer" variable now holds "Hello, World!"
if type(Buffer) ~= "buffer" then
warn("Buffer new value:", typeof(Buffer), Buffer);
error("Buffer is no longer a buffer!!", 0);
end
--// 2 lines of code below here actually doesnt matter but "Buffer" variable doesnt change when we remove anything below here.
repeat pcall(1) until true;
Var1 = nil;
end
--// Doesnt make much sense but we also need this in a loop
repeat
Bug();
until true
if type(Buffer) == "buffer" then
--// Warn in console if our variable did not get changed
warn("Code ran as expected. (variable was not modified)");
end
Code works as expected without native execution.
As you can also probably tell I found this completely on accident so the code is kinda messy.