© 2026 Hedgehog Software, LLC

TwitterGitHubDiscord
More
CommunitiesDocsAboutTermsPrivacy
Search
Star
Setup for Free
C#C
C#•2y ago•
5 replies
PaperClip

Question about Static Readonly Field optimization in Tier 2 JIT ASM

According to this article about dotnet 7 performance improvements:

There are various things the JIT can learn about a method during tier-0 that it can then use for tier-1. For example, the very fact that the tier-0 code executed means that any statics accessed by the method will have been initialized, and that means that any readonly statics will not only have been initialized by the time the tier-1 code executes but their values won’t ever change.

I wondered what would happen if the value of this field was changed after a constant was compiled into assembly. You are still able to change the field value with unsafe code (Reflection throws a
FieldAccessException
FieldAccessException
).

In this example the disassembled code shows how the
Test()
Test()
method has been reduced to only a constant. However, running the program shows that updating the value of the static readonly field the method also updates. How does this work? Am I testing something wrong, or is the JIT able to detect the fact that the field as been altered and recompile the method?

Program output:
True
True
False
False
True
True
False
False


ASM via benchmarkdotnet
; StaticReadonlyField.Program.Test()
       mov       eax,1
       ret
; Total bytes of code 6
; StaticReadonlyField.Program.Test()
       mov       eax,1
       ret
; Total bytes of code 6


CS:
[DisassemblyDiagnoser]
public class Program
{
    static readonly bool Is64Bit = Environment.Is64BitProcess;


    static void Main(string[] args)
    {
        BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

        Console.WriteLine("Done");
        Console.ReadLine();

        Console.WriteLine(Is64Bit);
        Console.WriteLine(new Program().Test());

        unsafe
        {
            fixed(bool* ptr = &Is64Bit)
            {
                *ptr = !Is64Bit;
            }
        }

        Console.WriteLine(Is64Bit);
        Console.WriteLine(new Program().Test());
    }

    [Benchmark]
    public bool Test() => Is64Bit;
}
[DisassemblyDiagnoser]
public class Program
{
    static readonly bool Is64Bit = Environment.Is64BitProcess;


    static void Main(string[] args)
    {
        BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);

        Console.WriteLine("Done");
        Console.ReadLine();

        Console.WriteLine(Is64Bit);
        Console.WriteLine(new Program().Test());

        unsafe
        {
            fixed(bool* ptr = &Is64Bit)
            {
                *ptr = !Is64Bit;
            }
        }

        Console.WriteLine(Is64Bit);
        Console.WriteLine(new Program().Test());
    }

    [Benchmark]
    public bool Test() => Is64Bit;
}
.NET BlogStephen Toub - MSFT
Performance Improvements in .NET 7 - .NET Blog
.NET 7 is fast. Really fast. This post deep-dives into hundreds of performance improvements that contributed to that reality.
Performance Improvements in .NET 7 - .NET Blog
C# banner
C#Join
We are a programming server aimed at coders discussing everything related to C# (CSharp) and .NET.
61,871Members
Resources
Was this page helpful?

Similar Threads

Recent Announcements

Similar Threads

readonly struct and readonly struct instance members (optimization?)
C#CC# / help
4y ago
ASM
C#CC# / help
3y ago
Cannot set readonly field in inherited constructor [Answered]
C#CC# / help
4y ago
Is it possible to use Reflection to replace a static readonly field without the static constructor?
C#CC# / help
2y ago