Lua vs. C#

Is it really worth it to learn C# over Lua for beginning your modding adventure.

Not sure if this have been discussed before, at least i could not find anything actually testing and comparing the performance of the two languages…
I tested out some “identical” code in C# and Lua on the client to see what the load of resource would be.


You can see the code for each resource below:

C#
using CitizenFX.Core;
using System.Threading.Tasks;
namespace Client
{
    public class MainClient : BaseScript
    {
        public MainClient()
        {
            Tick += Update;
        }
        public async Task Update()
        {
            for (int i = 0; i < 10; i++)
                TriggerEvent("chat:addMessage", new
                {
                    color = new[] { 255, 0, 0 },
                    multiline = true,
                    args = new[] {"Me",  "Very long message "}
                });
            await Delay(0);
        }
    }
}
Lua
Citizen.CreateThread(function()
    while true do
		for i=1,10 do
			TriggerEvent('chat:addMessage', {
				color = { 255, 0, 0},
				multiline = true,
				args = {"Me", "Very long message "}
			})
		end
		Citizen.Wait(0)
    end
end)

So, in order to check if these results are true. Could everyone try this or something similar out and post further results in comments? Remember to document the details.

1 Like

The 2 code examples aren’t equivalent. The C# code is adding 10 chat messages every other frame. Remove the await Delay(0) and then they will be essentially equivalent.

Non-async
public Task Update()
        {
            for (int i = 0; i < 10; i++)
                TriggerEvent("chat:addMessage", new
                {
                    color = new[] { 255, 0, 0 },
                    multiline = true,
                    args = new[] { "Me", "Very long message " }
                });
            //await Delay(0);
            return Task.FromResult(0);
        }

async without await
public async Task Update()
        {
            for (int i = 0; i < 10; i++)
                TriggerEvent("chat:addMessage", new
                {
                    color = new[] { 255, 0, 0 },
                    multiline = true,
                    args = new[] { "Me", "Very long message " }
                });
            //await Delay(0);
            //return Task.FromResult(0);
        }

Dont really seem to do any differene… I dont think it skips any frame…

1 Like

I mean, sure in the worst case there may be some glaring differences. But if you’re optimizing your code that’s where the very marginal difference comes in. In reality, you should never be having a resource taking that long to execute consistently. If you do, than your code needs some work.

Learning to optimize bad code is going to give you far greater results than learning a new language to try to gain some extra overhead for bad implementation. For a lot of people, the amount of resources available for learning how to do things in LUA pertaining to FiveM is going to be of far more benefit than what slight performance gain they’ll get in a real world situation moving to a different language.

Yes, there are performance differences, but your example does not represent any real world example. You should test performance invoking natives instead.

Either way, C# has a ~0.2ms overhead due to AppDomain. However, this overhead is practically negligible and won’t impact performance. Native invocation is slightly faster in Lua, but again quite negligible.

Choosing Lua vs C# vs Javascript/Typescript vs <insert any language that transpiles to any of the aforementioned> (like Kotlin) in the end all depends on your own subjective opinion of a language and your usecase.

When I want to test some natives real quick or create some other quick tests I write a Lua or JavaScript script. For bigger projects I go with C# or Typescript due to the object oriented nature (especially if C#).

In the end… It all depends. You shouldnt choose a language for performance though. Practically negligible across the board

4 Likes

:question: no?

1 Like

I’d like to really see good benchmark on it as I’m solely a C# developer (plus the nuget packages <3). Its pretty much my goto language for all kinds of application code, unless its web and then I live inside of the Angular CLI.

Also for that “overhead” comment, provide some evidence because I’m with Helium on that.

You guys are right, I thought it went down from ~0.4ms to ~0.2ms, but it’s now closer to ~0.1ms difference between an empty Lua vs C# resource.

Citizen.CreateThread(function()
    print("Initialized emptyresourcelua")
end)
namespace EmptyResourceTest
{
    public class Class1 : BaseScript
    {
        public Class1()
        {
            Debug.WriteLine("Initializezd EmptyResourceCsharp");
        }
    }
}

Either way, my point stands. The performance difference is negligible and choosing a scripting language more comes down to your own experience, comforts, the project use case and complexity.

Using BaseScript isn’t an “empty” csharp resource as BaseScript is doing things behind the scenes that a lua script would not be running, but thats me being picky…

Either way, I agree with your last statement.

EDIT: I see you’re using ~ as in Algebra, approximately equal I guess…