Repository navigation
Reflection performance in NativeAOT #66620
Copy link
Copy link
Open
Labels
Milestone
Description
Description
when I use the following example without NativeAOT, it's very fast, but with NativeAOT, I found it's very slow.
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Reflection;
namespace MyApp
{
public static class Utils
{
public static string GetDescription(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DescriptionAttribute attribute
= Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
as DescriptionAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
}
internal unsafe class Program
{
public enum Item
{
[Description("Zero")]
Useless,
[Description("Test--1")]
Test1,
[Description("Test--2")]
Test2,
[Description("Test--3")]
Test3,
[Description("Test--4")]
Test4,
[Description("Test--5")]
Test5,
[Description("Test--6")]
Test6,
[Description("Test--7")]
Test7,
[Description("Test--8")]
Test8,
[Description("Test--9")]
Test9,
[Description("Test--10")]
Test10,
[Description("Test--11")]
Test11,
[Description("Test--12")]
Test12,
[Description("Test--13")]
Test13,
[Description("Test--14")]
Test14,
[Description("Test--15")]
Test15,
[Description("Test--16")]
Test16,
[Description("Test--17")]
Test17,
[Description("Test--18")]
Test18,
[Description("Test--19")]
Test19,
[Description("Test--20")]
Test20,
[Description("Test--21")]
Test21,
[Description("Test--22")]
Test22,
[Description("Test--23")]
Test23,
[Description("Test--24")]
Test24,
[Description("Test--25")]
Test25,
[Description("Test--26")]
Test26,
[Description("Test--27")]
Test27,
[Description("Test--28")]
Test28,
[Description("Test--29")]
Test29,
[Description("Test--30")]
Test30,
[Description("Test--31")]
Test31,
[Description("Test--32")]
Test32,
[Description("Test--33")]
Test33,
[Description("Test--34")]
Test34,
[Description("Test--35")]
Test35,
[Description("Test--36")]
Test36
}
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
List<string> test1 = new List<string>();
for (int i = 0; i < 100000; i++)
{
test1.Add(Item.Test36.GetDescription());
}
sw.Stop();
Console.WriteLine("First Example: " + sw.ElapsedTicks);
sw.Restart();
sw.Start();
List<string> test2 = new List<string>();
for (int i = 0; i < 100000; i++)
{
test2.Add("test--36");
}
sw.Stop();
Console.WriteLine("Second Example: " + sw.ElapsedTicks);
Console.ReadKey();
}
}
}Output
Without NativeAOT
First Example: 1711806
Second Example: 10042
With NativeAOT
First Example: 5760899
Second Example: 20363
Configuration
Win-x64
.NET 6
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
hez2010 commentedon Mar 15, 2022
There's some performance degrade but not that huge. For performance test you need to use BenchmarkDotNet to get accurate result, rather than using a StopWatch around a loop iteration whose result can be affected by many other factors.
I ran it with BenchmarkDotNet and got this result:
List itself has no performance difference between JIT and NativeAOT, while reflection in NativeAOT is a bit slower than JIT.
AhmedZero commentedon Mar 15, 2022
I don't know benchmark.net works with NativeAOT and my program has those conditions and I program it like that.
when the program add a lot of elements to the list, the performance becomes bad.
jkotas commentedon Mar 15, 2022
Yes, this is what I am seeing as well.
AhmedZero commentedon Mar 20, 2022
NativeAOT
Without NativeAOT
you're correct @hez2010
[-]List Collection Performance in NativeAOT[/-][+]Reflection performance in NativeAOT[/+]AhmedZero commentedon Aug 23, 2025
BenchmarkDotNet v0.15.2, Windows 11 (10.0.26100.4946/24H2/2024Update/HudsonValley)
13th Gen Intel Core i7-13700HX 2.10GHz, 1 CPU, 24 logical and 16 physical cores
.NET SDK 9.0.304
[Host] : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
.NET 9.0 : .NET 9.0.8 (9.0.825.36511), X64 RyuJIT AVX2
NativeAOT 9.0 : .NET 9.0.8, X64 NativeAOT AVX2