Random Next .NET 8 performance improvements over .NET 7




Date Added (UTC):

15 Apr 2024 @ 20:04

Date Updated (UTC):

15 Apr 2024 @ 20:04


.NET Version(s):

.NET 7 .NET 8

Tag(s):

#.Net8PerfImprovement


Added By:
Profile Image

Blog   
Ireland    
.NET Developer and tech lead from Ireland!

Benchmark Results:





Benchmark Code:



using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Columns;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
using System;

[HideColumns("Error", "StdDev", "Median", "RatioSD")]
[MemoryDiagnoser(displayGenColumns: false)]
[Config(typeof(Config))]
public class RandomNext
{
    private static readonly Random s_rand = new();

    [Benchmark]
    public int NextMax() => s_rand.Next(12345);

    private class Config : ManualConfig
    {
        public Config()
        {
            AddJob(Job.Default.WithId(".NET 7").WithRuntime(CoreRuntime.Core70).AsBaseline());
            AddJob(Job.Default.WithId(".NET 8").WithRuntime(CoreRuntime.Core80));

            SummaryStyle =
                SummaryStyle.Default.WithRatioStyle(RatioStyle.Percentage);
        }
    }
}

// .NET 7, .NET 8
public int NextMax()
{
    return s_rand.Next(12345);
}

// .NET 7
.method public hidebysig 
    instance int32 NextMax () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 1b 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x208e
    // Code size 16 (0x10)
    .maxstack 8

    // sequence point: (line 28, col 29) to (line 28, col 47) in _
    IL_0000: ldsfld class [System.Runtime]System.Random RandomNext::s_rand
    IL_0005: ldc.i4 12345
    IL_000a: callvirt instance int32 [System.Runtime]System.Random::Next(int32)
    IL_000f: ret
}

// .NET 8
.method public hidebysig 
    instance int32 NextMax () cil managed 
{
    .custom instance void [BenchmarkDotNet.Annotations]BenchmarkDotNet.Attributes.BenchmarkAttribute::.ctor(int32, string) = (
        01 00 1b 00 00 00 01 5f 00 00
    )
    // Method begins at RVA 0x2050
    // Code size 16 (0x10)
    .maxstack 8

    // sequence point: (line 28, col 29) to (line 28, col 47) in _
    IL_0000: ldsfld class [System.Runtime]System.Random RandomNext::s_rand
    IL_0005: ldc.i4 12345
    IL_000a: callvirt instance int32 [System.Runtime]System.Random::Next(int32)
    IL_000f: ret
}

// .NET 7 Jit Asm Code unavailable due to errors:
Type RandomNext has a static constructor, which is not supported by SharpLab JIT decompiler.
// .NET 8 Jit Asm Code unavailable due to errors:
Type RandomNext has a static constructor, which is not supported by SharpLab JIT decompiler.


Benchmark Description:


The provided benchmark code is structured to evaluate the performance of the `Random.Next` method in .NET, specifically comparing its execution speed and efficiency across different .NET runtime versions. Below is an overview of the setup and a detailed explanation of the benchmark method, including the rationale behind it and what it aims to measure. ### General Setup Overview - **BenchmarkDotNet**: This is a powerful .NET library that makes it easy to benchmark .NET applications, providing detailed insights into the performance of your code. - **Configuration**: The benchmark class is configured using the `Config` inner class, which extends `ManualConfig`. This configuration specifies the .NET runtime versions to test against, in this case, .NET 7 and .NET 8, with .NET 7 set as the baseline for comparison. - **.NET Versions**: The benchmark is explicitly designed to compare the performance of code running on .NET 7 and .NET 8, showcasing the differences in performance that might arise from the runtime improvements or regressions. - **Memory Diagnoser**: Enabled with `displayGenColumns: false` to focus on the total memory allocation without breaking it down by generation, which helps in understanding the memory efficiency of the method being tested. - **Hide Columns**: Certain columns like "Error", "StdDev", "Median", and "RatioSD" are hidden to simplify the output and focus on the most relevant metrics for this benchmark. ### Benchmark Method: `NextMax` #### Purpose The `NextMax` method is designed to measure the performance of generating a random number within a specific range using the `System.Random` class. This is a common operation in many applications, ranging from simulations to games, and understanding its performance characteristics is crucial for optimizing applications that rely heavily on random number generation. #### Performance Aspect Being Tested - **Execution Speed**: How quickly the `Random.Next` method can generate a random number within the specified range (`12345` in this case). This is crucial for applications that require a high volume of random numbers generated in a short amount of time. - **Memory Efficiency**: While the primary focus is on execution speed, the memory diagnoser setup (though not displaying generation columns) allows for observing if there's any significant memory allocation involved in calling this method, which could be relevant for high-frequency calls in a tight loop. #### Expected Results or Insights - **Runtime Comparison**: By running this benchmark, you should expect to see how the performance of `Random.Next` compares between .NET 7 and .NET 8. If there are runtime optimizations in .NET 8, those might manifest as faster execution times or reduced memory allocations. - **Performance Baseline**: Establishing a performance baseline for `Random.Next` on .NET 7 allows for a clear comparison with future .NET versions, helping to identify if upgrades to the runtime environment will offer significant performance improvements for this operation. - **Optimization Opportunities**: Understanding the performance characteristics of `Random.Next` can also highlight opportunities for optimization, such as caching random numbers or reusing `Random` instances, depending on the specific needs and constraints of your application. In summary, this benchmark is intended to provide insights into the efficiency and speed of generating random numbers within a specific range in .NET applications, offering valuable data for developers looking to optimize their applications or make informed decisions about upgrading to newer .NET versions.


Benchmark Comments: