CodegenAnalysis.Assertions
1.0.0
dotnet add package CodegenAnalysis.Assertions --version 1.0.0
NuGet\Install-Package CodegenAnalysis.Assertions -Version 1.0.0
<PackageReference Include="CodegenAnalysis.Assertions" Version="1.0.0" />
paket add CodegenAnalysis.Assertions --version 1.0.0
#r "nuget: CodegenAnalysis.Assertions, 1.0.0"
// Install CodegenAnalysis.Assertions as a Cake Addin #addin nuget:?package=CodegenAnalysis.Assertions&version=1.0.0 // Install CodegenAnalysis.Assertions as a Cake Tool #tool nuget:?package=CodegenAnalysis.Assertions&version=1.0.0
CodegenAnalysis
<img align="right" src="./logo1t.png" width=200>
Library for analyzing the machine code generated by JIT (codegen). Has API for obtaining the codegen, verifying the characteristics for tests (in a similar manner to xUnit), and generating reports as benchmarks (in a similar manner to BenchmarkDotNet). Supports x86_64 on three major platforms (Windows, MacOS, Linux).
Why should I use it?
First of all, most .NET developers don't need this library. If you want to measure performance of your code, use BenchmarkDotNet.
If you're working on low-level, often HW-related project, where it's crucial if a branch or call or etc. is optimized or not, this library is for you.
Table of contents
CodegenAnalysis
static int AddAndMul(int a, int b) => a + b * a;
...
var ci = CodegenInfo.Obrain(() => AddAndMul(3, 5));
Console.WriteLine(ci);
Output:
00007FFD752E42F0 8BC2 mov eax,edx
00007FFD752E42F2 0FAFC1 imul eax,ecx
00007FFD752E42F5 03C1 add eax,ecx
00007FFD752E42F7 C3 ret
CodegenAnalysis.Assertions
Verifying the size of the codegen
using CodegenAssertions;
using Xunit;
public class CodegenSizeTest
{
public static int SomeMethod(int a, int b)
=> a + b;
[Fact]
public void Test1()
{
CodegenInfo.Obtain(() => SomeMethod(4, 5), CompilationTier.Tier1)
.ShouldBeNotLargerThan(20);
}
}
Having calls in the codegen
public class Tests
{
public class A
{
public virtual int H => 3;
}
public sealed class B : A
{
public override int H => 6;
}
// this will get devirtualized at tier1, but not at tier0
static int Twice(B b) => b.H * 2;
[Fact]
public void NotDevirtTier0()
{
CodegenInfo.Obtain(() => Twice(new B()), CompilationTier.Default)
.ShouldHaveCalls(c => c >= 1);
}
[Fact]
public void DevirtTier1()
{
CodegenInfo.Obtain(() => Twice(new B()), CompilationTier.Tier1)
.ShouldHaveCalls(0);
}
}
Testing if we have branches
private static readonly bool True = true;
static int SmartThing()
{
if (True)
return 5;
return 10;
}
[Fact]
public void BranchElimination()
{
CodegenInfo.Obtain(() => SmartThing())
.ShouldHaveBranches(0);
}
[MethodImpl(MethodImplOptions.NoOptimization)]
static int StupidThing()
{
if (True)
return 5;
return 10;
}
[Fact]
public void NoBranchElimination()
{
CodegenInfo.Obtain(() => StupidThing(), CompilationTier.Default)
.ShouldHaveBranches(b => b > 0);
}
CodegenAnalysis.Benchmarks
CodegenBenchmarkRunner.Run<A>();
[CAJob(Tier = CompilationTier.Default),
CAJob(Tier = CompilationTier.Tier1)]
[CAColumn(CAColumn.Branches),
CAColumn(CAColumn.Calls),
CAColumn(CAColumn.CodegenSize),
CAColumn(CAColumn.StaticStackAllocations)]
[CAExport(Export.Html),
CAExport(Export.Md)]
public class A
{
[CAAnalyze(3.5f)]
[CAAnalyze(13.5f)]
public static float Heavy(float a)
{
var b = Do1(a);
var c = Do1(b);
if (a > 10)
c += Aaa(a);
return c + b;
}
[CAAnalyze(6f)]
public static float Square(float a)
{
return a * a;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static float Do1(float a)
{
return a * 2;
}
[MethodImpl(MethodImplOptions.NoInlining)]
public static float Aaa(float h)
{
return h * h * h;
}
}
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- CodegenAnalysis (>= 1.0.0)
-
.NETStandard 2.1
- CodegenAnalysis (>= 1.0.0)
-
net5.0
- CodegenAnalysis (>= 1.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 879 | 8/14/2022 |
0.2.0-alpha | 568 | 8/10/2022 |
0.1.0-alpha-1659621383-f874603 | 586 | 8/4/2022 |
0.1.0-alpha-1639660460-222ddd2 | 641 | 12/16/2021 |
0.1.0-alpha-1639290344-32dff2a | 589 | 12/12/2021 |
0.0.10-alpha | 635 | 12/10/2021 |
0.0.9-alpha | 595 | 12/7/2021 |
0.0.8-alpha | 613 | 12/5/2021 |
0.0.7-alpha | 625 | 11/30/2021 |
0.0.6-alpha | 629 | 11/28/2021 |
0.0.5-alpha | 600 | 11/27/2021 |
0.0.4-alpha | 645 | 11/27/2021 |
0.0.3-alpha | 2,938 | 11/25/2021 |
0.0.0-alpha-1639289799-a37ffcf | 611 | 12/12/2021 |
Forward jumps visualization and bugs fixed.