saul / demofile-net

Blazing fast cross-platform demo parser library for Counter-Strike 2, written in C#.
MIT License
76 stars 7 forks source link

Performance issues #57

Open xGuysOG opened 2 months ago

xGuysOG commented 2 months ago

Research

Description

Performance issues, in the Git you state that parsing a whole 1 hour demo can be done in 1.5 seconds.

i have a pc with 64 gigs of ddr5 AMD Ryzen 7 7800X3D RTX 3070ti running on a nvme drive.

but i am getting 8-10 seconds to just run this demo that ended 13-4. like 20 minutes of gameplay. Am i doing something wrong here? it seems rather slow.

Test was done on a console application on .net 8 with the below code.

Code to reproduce

public static async Task Main(string[] args)
    {
        await using var fileStream = File.OpenRead(demoFilePath);
        Stopwatch stopwatch3 = new Stopwatch();
        stopwatch3.Start();
        bool bombExploded = false;
        var demo = new DemoParser();

        demo.Source1GameEvents.BombExploded += e =>
        {
            Console.WriteLine("Bomb exploded");
            bombExploded = true;
        };

        demo.Source1GameEvents.RoundStart += e =>
        {

            if (!demo.GameRules.HasMatchStarted)
            {
                //PowerLigaManager.Log("ROund end called but we have an issue, it seems match was not started yet");
                return;
            }
            Console.WriteLine("Round start called at round ct:" + demo.TeamCounterTerrorist.Score + " and t:" + demo.TeamTerrorist.Score);
        };

            demo.Source1GameEvents.CsWinPanelMatch += e =>
        {
            Console.WriteLine("WIn match has ended");
        };
        await demo.ReadAllAsync(fileStream); 
        stopwatch3.Stop();
        Console.WriteLine("Time elapsed: {0}", stopwatch3.Elapsed);
        Console.WriteLine("\nFinished!");
    }

Affected demos

https://drive.google.com/file/d/1Oi80oKMHf2DvIYSI42UL4kxvICLMGj2G/view?usp=sharing

in0finite commented 2 months ago

I am parsing the specified demo in 1.9 sec in my AOT compiled build, so you are probably doing something wrong.

Are you maybe running it in Debug mode ?

Also, could you run the Benchmark project and check the results. It should give you 1.5 sec as a mean time.

xGuysOG commented 2 months ago

I am parsing the specified demo in 1.9 sec in my AOT compiled build, so you are probably doing something wrong.

Are you maybe running it in Debug mode ?

Also, could you run the Benchmark project and check the results. It should give you 1.5 sec as a mean time.

Benchmark gave me 1.1 sec as mean time on my own demo

i did some changes and switched to reading the bytes as async and adding them to the memory stream and running it in visual studio as release is down to 2.7 seconds

if just build the exe and run it as release its 2.8 seconds

current code: public static class Program { public static string demoFilePath = "D:\Testing\Sæson 26\3divD\UnsignedPuggers_vs_EspergrdeEsport_map1_de_anubis_2024-04-16_18-01-26_661577d64c197423489bdcef_1713290486749\661577d64c197423489bdcef_0_1713290486749.dem";

public static async Task Main(string[] args)
{
    Stopwatch stopwatch3 = new Stopwatch();
    stopwatch3.Start();
    MemoryStream _fileStream;
    byte[] _demoBytes;
    _demoBytes = await File.ReadAllBytesAsync(demoFilePath);
    _fileStream = new MemoryStream(_demoBytes);

    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    var demo = new DemoParser();

    demo.Source1GameEvents.BombExploded += e =>
    {
        Console.WriteLine("Bomb exploded");
    };

    demo.Source1GameEvents.RoundStart += e =>
    {

        if (!demo.GameRules.HasMatchStarted)
        {
            //PowerLigaManager.Log("ROund end called but we have an issue, it seems match was not started yet");
            return;
        }
        Console.WriteLine("Round start called at round ct:" + demo.TeamCounterTerrorist.Score + " and t:" + demo.TeamTerrorist.Score);
        Debug.WriteLine("Round start called at round ct:" + demo.TeamCounterTerrorist.Score + " and t:" + demo.TeamTerrorist.Score);
    };

    demo.Source1GameEvents.CsWinPanelMatch += e =>
{
    Console.WriteLine("WIn match has ended");
};
    await demo.ReadAllAsync(_fileStream);
    stopwatch3.Stop();

    stopwatch.Stop();
    Console.WriteLine("Time elapsed after file data: {0}", stopwatch.Elapsed);
    Console.WriteLine("Time elapsed: {0}", stopwatch3.Elapsed);
    Console.WriteLine("\nFinished!");
    Console.ReadKey();
}
in0finite commented 2 months ago

Now you just need to build it using AOT compiler, and it should give you maxed out performance.

There's also PR in progress which enables multi-threaded parsing ...

saul commented 2 months ago

Using multithreaded parsing I can read that demo in 1.9 secs on my Ryzen 7 3800X on an NVMe drive also. I believe for this workload at least .NET seems to run faster on ARM64 than x64 (the benchmark in the readme is on an Apple M1).

I'll try to get the multithreaded parsing merged asap.