Home

Awesome

RapidEnum

日本語版

RapidEnum is a Source Generator that provides fast-running enum utilities for C#/.NET. It is faster than the .NET API and achieves zero allocation for all methods.

Package - RapidEnum

PerformanceComparison

It performed better than .NET API. It is also faster than FastEnum v1.8.0. For more information on performance comparisons, see this.

RapidEnum is heavily influenced by FastEnum. API is very similar to FastEnum. Thanks to xin9le for creating a great library!

Table of Contents

Requirements

Installation

NuGet

$ dotnet add package RapidEnum

nuget.org : RapidEnum

Unity

Add the following git URL from the Package Manager

https://github.com/hanachiru/RapidEnum.git?path=/RapidEnum.Unity/Packages/com.hanachiru.rapidenum

UPM

asmdef settings

If you have not created .asmdef, the following is not relevant.

If you have Override References in the .asmdef switched on, you need to add RapidEnum.Core.dll to the Assembly References.

<img src="./Images/AssemblyReferences.png" width="300" />

How to use

Basic usage

Attaching [RapidEnum] to the target enum generates an enum utility class. Note that this is only valid for public or internal enum.

[RapidEnum]
public enum Weather
{
    Sun,
    Cloud,
    Rain,
    Snow
}

The Enum name + EnumExtensions class defines the relevant methods.

// Sun,Cloud,Rain,Snow
IReadOnlyList<Weather> values = WeatherEnumExtensions.GetValues();

// Sun,Cloud,Rain,Snow
IReadOnlyList<string> names = WeatherEnumExtensions.GetNames();

// Rain
string name = WeatherEnumExtensions.GetName(Weather.Rain);

// Cloud
string str = Weather.Cloud.ToStringFast();

// True
bool defined = WeatherEnumExtensions.IsDefined("Sun");

// Sun
Weather parse = WeatherEnumExtensions.Parse("Sun");

// True
// Sun
bool tryParse = WeatherEnumExtensions.TryParse("Sun", out Weather value);

How to use it for any enum

The [RapidEnumWithType] can be used to generate utility classes for any enum.

For static partial class that are public or internal, give them a [RapidEnumWithType] with the target enum as an argument. The class name can be any string, but Enum name + EnumExtensions is easier to understand.

// System.DateTimeKind has Unspecified, Utc, Local
[RapidEnumWithType(typeof(DateTimeKind))]
public static partial class DateTimeKindEnumExtensions
{
}

There is no performance difference compared to using [RapidEnum]. Use [RapidEnumWithType] if [RapidEnum] cannot be given, such as an enum provided by a third-party library.

// Unspecified,Utc,Local
IReadOnlyList<DateTimeKind> values = DateTimeKindEnumExtensions.GetValues();

// Unspecified,Utc,Local
IReadOnlyList<string> names = DateTimeKindEnumExtensions.GetNames();

// Local
string name = DateTimeKindEnumExtensions.GetName(DateTimeKind.Local);

// Local
string str = DateTimeKind.Local.ToStringFast();

// True
bool defined = DateTimeKindEnumExtensions.IsDefined("Local");

// Local
DateTimeKind parse = DateTimeKindEnumExtensions.Parse("Local");

// True
// Local
bool tryParse = DateTimeKindEnumExtensions.TryParse("Local", out DateTimeKind value);

Get Name and Value as a pair

Use the GetMembers and GetMember methods if you want to get the Name and Value of enum in pairs.

WeatherEnumExtensions.Member member = WeatherEnumExtensions.GetMember(Weather.Rain);
var (name, value) = member;

foreach (WeatherEnumExtensions.Member item in WeatherEnumExtensions.GetMembers())
{
    Console.WriteLine($"Name : {item.Name}, Value : {item.Value}");
}

Performance comparison

MethodMeanErrorStdDevMedianGen0Allocated
RapidEnum_GetValues0.0042 ns0.0059 ns0.0052 ns0.0028 ns--
FastEnum_GetValues0.0083 ns0.0086 ns0.0081 ns0.0055 ns--
NET_GetValues64.4620 ns0.9908 ns0.9268 ns64.2767 ns0.004840 B
RapidEnum_GetNames0.0006 ns0.0017 ns0.0015 ns0.0000 ns--
FastEnum_GetNames0.0025 ns0.0031 ns0.0028 ns0.0012 ns--
NET_GetNames12.3820 ns0.1086 ns0.1016 ns12.4076 ns0.006756 B
RapidEnum_GetName0.0069 ns0.0085 ns0.0071 ns0.0039 ns--
FastEnum_GetName0.2530 ns0.0070 ns0.0065 ns0.2527 ns--
NET_GetName15.9190 ns0.0524 ns0.0490 ns15.9046 ns0.002924 B
RapidEnum_ToString0.0103 ns0.0049 ns0.0046 ns0.0110 ns--
FastEnum_ToString0.4844 ns0.0062 ns0.0052 ns0.4845 ns--
NET_ToString6.1700 ns0.0451 ns0.0376 ns6.1493 ns0.002924 B
RapidEnum_IsDefines0.0026 ns0.0036 ns0.0034 ns0.0000 ns--
FastEnum_IsDefines4.6724 ns0.0583 ns0.0545 ns4.6434 ns--
NET_IsDefines14.5923 ns0.0355 ns0.0332 ns14.5996 ns--
RapidEnum_Parse0.9258 ns0.0161 ns0.0150 ns0.9240 ns--
FastEnum_Parse4.6223 ns0.0082 ns0.0073 ns4.6192 ns--
NET_Parse8.8707 ns0.0965 ns0.0903 ns8.8293 ns--
RapidEnum_TryParse0.7633 ns0.0097 ns0.0090 ns0.7657 ns--
FastEnum_TryParse4.6869 ns0.0254 ns0.0212 ns4.6852 ns--
NET_TryParse8.8433 ns0.0609 ns0.0569 ns8.8268 ns--

PerformanceComparison

Benchmark Source

BenchmarkDotNet v0.14.0, macOS Sonoma 14.4.1 (23E224) [Darwin 23.4.0]
Apple M2 Pro, 1 CPU, 12 logical and 12 physical cores
.NET SDK 8.0.303
[Host]     : .NET 8.0.7 (8.0.724.31311), Arm64 RyuJIT AdvSIMD
DefaultJob : .NET 8.0.7 (8.0.724.31311), Arm64 RyuJIT AdvSIMD