szehetner / inlininganalyzer Goto Github PK
View Code? Open in Web Editor NEWInlining Analyzer is a Visual Studio Extension that shows in the source code if a method call will be inlined by the JIT compiler.
License: MIT License
Inlining Analyzer is a Visual Studio Extension that shows in the source code if a method call will be inlined by the JIT compiler.
License: MIT License
Hello,
I'm having some trouble running this extension and would like to ask for your kind assistance. I searched for an answer before but found nothing.
In VS 2019, I tried to run the inline analysis as suggested by the documentation, by using the context menu inside a C# method and selecting "Run Inlining Analyzer on Current Scope". This is the output:
Publishing project to C:\Users\asdf\AppData\Local\Temp\InliningAnalyzer_1
Microsoft (R) Build Engine version 16.11.0+0538acc04 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
MSBUILD : error MSB1011: Specify which project or solution file to use because this folder contains more than one project or solution file.
No highlighting or other output appears after this. I found no way around so far.
Tool exception: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.
Tool output: inlining_analyzer.log
Tool preffered runtime: NetCore
.NET information: dotnet_info.log
Project target frameworks: netstandard1.1+netstandard2.0
Project source code: https://github.com/alexanderkozlenko/json-rpc
Please support VS 2022
When trying to run analysis on asp net core app 2.2, I got lot of FileNotFound errors. I suspect that's related to new csproj package reference format as version number is not specified for Microsoft.AspNetCore.App
Version used : 0.7.4
dotnet --info => 2.2.100
Publishing project to C:\Users\me\AppData\Local\Temp\InliningAnalyzer_1
Microsoft (R) Build Engine version 15.9.20+g88f5fadfbe pour .NET Core
Copyright (C) Microsoft Corporation. Tous droits r‚serv‚s.
MyApi -> C:\Users\me\AppData\Local\Temp\InliningAnalyzer_1\
Starting Inlining Analyzer...
TargetFramework: netcoreapp2.2
Assembly: C:\Users\me\AppData\Local\Temp\InliningAnalyzer_1\MyApi.dll
Runtime: NetCore
Platform: X64
Scope: All Types and Methods
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Le fichier sp‚cifi‚ est introuvable.
File name: 'Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.IO.FileNotFoundException: Could not load the specified file.
File name: 'Microsoft.AspNetCore.Mvc.Core'
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Le fichier sp‚cifi‚ est introuvable.
File name: 'Microsoft.AspNetCore.Mvc.Core, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' ---> System.IO.FileNotFoundException: Could not load the specified file.
File name: 'Microsoft.AspNetCore.Mvc.Core'
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
...
Hello
Curious, InliningAnalyzer support projects using .NET Core 2.0?
In my case, I getting crash when trrying to run it on one of my project.
If you need project to repro, give me your email, I'll send you for analyzing.
P.S. Please add "Analyze file with InlineAnalyzer" to right-mouse-button menu when you click on file in project, like PVS-Studio: https://i.imgur.com/DfjY59f.png
Hi,
Trying to use your tool Vs2019 with a .net 5.0 project.
Having this problem
System.IO.FileNotFoundException: Impossible de charger le fichier ou l'assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' ou une de ses d‚pendances. Le fichier sp‚cifi‚ est introuvable.
Nom de fichierÿ: 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Admittedly I am trying this on an F# project (which is probably not supported.
In VS 2017 I do get the Inlining Analyzer menu item in Tools, but not in VS2019 Preview r
In VS 2017 in my F# (dotnet SDK project type) Project I do get the tools menu item.
The following error thrown from Tools\Inlining Analyzer\Run Inlining Analyzer on (current project).
Running the assembly analyzer apparently succeeds, but no highlighting. From the looks of the error it appears to be in the highlighting.
System.AggregateException: One or more errors occurred. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at VsExtension.Model.CodeModel.GetMethodCall(Cache doc, TextSpan textSpan) in C:\work\GitHub\InliningAnalyzer\src\VsExtension\Model\CodeModel.cs:line 33
at VsExtension.QuickInfo.QuickInfoSource.AugmentQuickInfoSession(IQuickInfoSession session, IList`1 qiContent, ITrackingSpan& applicableToSpan) in C:\work\GitHub\InliningAnalyzer\src\VsExtension\QuickInfo\QuickInfoSource.cs:line 75
at Microsoft.VisualStudio.Language.Intellisense.Implementation.LegacyQuickInfoSource.AugmentQuickInfoSession(IAsyncQuickInfoSession session, IList`1 content, ITrackingSpan& applicableToSpan)
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoSession.<TryComputeContentFromLegacySourceAsync>d__46.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoSession.<ComputeSourceContentAsync>d__39.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)
--- End of inner exception stack trace ---
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoSession.<UpdateAsync>d__32.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoPresentationSession.<UpdateAsync>d__5.MoveNext()
---> (Inner Exception #0) System.NullReferenceException: Object reference not set to an instance of an object.
at VsExtension.Model.CodeModel.GetMethodCall(Cache doc, TextSpan textSpan) in C:\work\GitHub\InliningAnalyzer\src\VsExtension\Model\CodeModel.cs:line 33
at VsExtension.QuickInfo.QuickInfoSource.AugmentQuickInfoSession(IQuickInfoSession session, IList`1 qiContent, ITrackingSpan& applicableToSpan) in C:\work\GitHub\InliningAnalyzer\src\VsExtension\QuickInfo\QuickInfoSource.cs:line 75
at Microsoft.VisualStudio.Language.Intellisense.Implementation.LegacyQuickInfoSource.AugmentQuickInfoSession(IAsyncQuickInfoSession session, IList`1 content, ITrackingSpan& applicableToSpan)
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoSession.<TryComputeContentFromLegacySourceAsync>d__46.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.VisualStudio.Language.Intellisense.Implementation.AsyncQuickInfoSession.<ComputeSourceContentAsync>d__39.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)
Is it possible to configure which colours are used for the highlighting? I'm colourblind, and the colours used are unfortunately too similar for me to easilt discern.
What's the licence for this?
Hi,
I'm trying to run the analyzer against my .NET standard project which is an analyzer.
(source code: https://github.com/RalfKoban/MiKo-Analyzers )
Unfortunately, I get a lot of FileNotFoundExceptions reported as the analyzer cannot find the Microsoft.CodeAnalysis
DLL.
Log:
Microsoft (R)-Build-Engine, Version 16.1.76+g14b0a930a7 f�r .NET Core
Copyright (C) Microsoft Corporation. Alle Rechte vorbehalten.
MiKo.Analyzer -> C:\Users\RKoban\AppData\Local\Temp\InliningAnalyzer_1\
Starting Inlining Analyzer...
TargetFramework: netstandard2.0
Assembly: C:\Users\RKoban\AppData\Local\Temp\InliningAnalyzer_1\MiKoSolutions.Analyzers.dll
Runtime: NetCore
Platform: X64
Scope: All Types and Methods
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Das System kann die angegebene Datei nicht finden.
File name: 'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ---> System.IO.FileNotFoundException: Could not load the specified file.
File name: 'Microsoft.CodeAnalysis'
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingEvent(AssemblyName assemblyName)
at System.Runtime.Loader.AssemblyLoadContext.ResolveUsingResolvingEvent(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. Das System kann die angegebene Datei nicht finden.
File name: 'Microsoft.CodeAnalysis, Version=2.10.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' ---> System.IO.FileNotFoundException: Could not load the specified file.
...
I'm not sure if this is somehow related to the fix for #11, however it would be nice if the inlining analyzer would work.
Best regards,
Ralf
I’ve landed today in this repository after reading
https://mattwarren.org/2019/03/01/Is-CSharp-a-low-level-language/
Both the post and this tool look like excellent ways of getting more insights in the performance of an application.
Unfortunately I’m not getting paid to build cool raytracers in c#, but to write boring c# database applications.
I typically use a my own framework to do this (Signum Framework) that has, just as entity framework, a LINQ provider.
When training people, very often they have problems knowing if a query is going to be resolved in the database or in memory. Will be awesome to have a VS extension that highlights any lambda that will be converted to an expression tree, and any method that returns IQueryable.
I’m thinking in starting a new VS extension based on this one.
Can I ask you questions if I have any problem?
Thanks
The analyzer seems to have some issues with methods that return value types by reference.
Consider this code below:
using System;
namespace InliningAnalyzerIgnoresRefReturnMethods
{
public class Program
{
private static int a;
private static int b;
private static ref int Select(bool which)
=> ref (which ? ref a : ref b);
private static int Select2(bool which)
=> Select(which);
public static void Main(string[] args)
{
ref int x = ref Select(true);
int y = Select(true);
int z = Select2(true); // <-- Commenting out this line causes the call to Select by Select2 to be highlighted.
Console.WriteLine(x);
Console.WriteLine(y);
}
}
}
If you run the analyzer, none of the calls to Select
are highlighted:
Oddly enough, if you comment out the call to Select2
, its call to Select
in it is highlighted:
Even more strange, turning off "Prefer 32-bit" or explicitly choosing x64 will also fix Select2
's call to Select
.
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static unsafe void ElementWiseAddAVX(float* ptr_a, float right, float* ptr_res, long length)
{
float* ptr_b = &right;
{
for (long i = 0; i < length / Vector256<float>.Count * Vector256<float>.Count; i += Vector256<float>.Count)
{
Vector256<float> v1 = Avx2.LoadVector256(&ptr_a[i]);
Vector256<float> v2 = Avx2.BroadcastScalarToVector256(ptr_b);
Vector256<float> res = Avx2.Add(v1, v2);
Avx2.Store(&ptr_res[i], res);
}
for (long i = length / Vector256<float>.Count * Vector256<float>.Count; i < length; i++)
{
ptr_res[i] = ptr_a[i] + *ptr_b;
}
}
}
This code gives compilation error.
The output window is showing the following error message:
Starting Inlining Analyzer...
Assembly: x.dll
Runtime: NetFramework
Platform: X64
Scope: All Types and Methods
Method A.B(generic class C1<!!0> (class System.Func
1<!!0>)) could not be found.
System.NullReferenceException: Object reference not set to an instance of an object.
at InliningAnalyzer.EtwSignatureMapper.GetTypename(Type type)
at InliningAnalyzer.EtwSignatureMapper.ParametersMatch(ParameterInfo[] parameters, String[] signatureParameters)
at InliningAnalyzer.EtwSignatureMapper.SelectOverload(MethodBase[] candidates, String signature)
at InliningAnalyzer.OrderedMethodProvider.d__4.MoveNext()
at InliningAnalyzer.JitCompilerHost.CompileMethods()
at InliningAnalyzer.JitCompilerHost.PreJITMethods()
Finished Inlining Analyzer
Some code:
public static C<T> B<T>(Func<T> action)
public class C
{
..
}
public class C<T> : C
Is this enough to identify the issue?
Seperate issue to track suggestion by @Krakean in #5
Please add "Analyze file with InlineAnalyzer" to right-mouse-button menu when you click on file in project, like PVS-Studio: https://i.imgur.com/DfjY59f.png
class Program
{
int inli(string f)
{
return int.Parse(f);
}
int ninli(string f)
{
try
{
return int.Parse(f);
}
catch (Exception e)
{
return 0;
}
}
void Main(string[] args)
{
inli("s");
ninli("h");
}
}
<OutputType>Library</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<PlatformTarget>x64</PlatformTarget>
the configuration of inlining analyzer has not been modified.
when the output window outputs finished inlining analyzer, there is no change on the code view.
so, I want to know what I missed.
thanks
Off the heels of #9, I've found another quirk around values by reference, this time with parameters:
using System;
namespace InliningAnalyzerIgnoresRefReturnMethods
{
public class Program
{
private static int a;
private static int b;
private static ref int Select(ref bool which)
=> ref (which ? ref a : ref b);
private static int Select2(ref bool which)
=> Select(ref which);
public static void Main(string[] args)
{
bool which = true;
ref int x = ref Select(ref which);
int y = Select(ref which);
int z = Select2(ref which);
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(z);
}
}
}
(Note that the which
parameter is passed by reference now.)
If you run the analyzer, none of the calls to Select
are highlighted:
Unlike last time, I did not observe any weirdness involving 32 vs 64 bit or commenting out the Select2
call.
It would be really nice if you could add the coloring of inlining of the overloaded operator. There can be a big difference in performance when you have an overloaded operator in a struct. The performance of the Struct can be much better with Public Fields compared to Auto Properties.
Example: The following Benchmark tells me that calling the + operator of the VecWithFields is inlined and the VecWithProperties is not. The + sign in the 'r = p + r;' line should be green or red.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System;
namespace ConsoleApp1 {
class Program {
static void Main(string[] args) {
BenchmarkRunner.Run<BM>();
}
}
public class BM {
[Benchmark(Baseline = true)]
public VecWithFields TestVecWithFields() {
var p = new VecWithFields(12f, 5f, 1.5f);
var r = new VecWithFields();
for (int i = 0; i < 100000; i++) {
r = p + r;
//r = p * r;
}
return r;
}
[Benchmark]
public VecWithProperties TestVecWithProperties() {
var p = new VecWithProperties(12f, 5f, 1.5f);
var r = new VecWithProperties(); ;
for (int i = 0; i < 100000; i++) {
r = p + r;
//r = p * r;
}
return r;
}
[Benchmark]
public ReadOnlyVecWithProperties TestReadOnlyVecWithProperties() {
var p = new ReadOnlyVecWithProperties(12f, 5f, 1.5f);
var r = new ReadOnlyVecWithProperties(); ;
for (int i = 0; i < 100000; i++) {
r = p + r;
//r = p * r;
}
return r;
}
public struct VecWithFields {
public float X;
public float Y;
public float Z;
public VecWithFields(float x, float y, float z) {
this.X = x;
this.Y = y;
this.Z = z;
}
public static VecWithFields operator *(VecWithFields q, VecWithFields r) {
return new VecWithFields(q.X * r.X, q.Y * r.Y, q.Z * r.Z);
}
public static VecWithFields operator +(VecWithFields q, VecWithFields r) {
return new VecWithFields(q.X + r.X, q.Y + r.Y, q.Z + r.Z);
}
}
public struct VecWithProperties {
public float X { get; set; }
public float Y { get; set; }
public float Z { get; set; }
public VecWithProperties(float x, float y, float z) {
this.X = x;
this.Y = y;
this.Z = z;
}
public static VecWithProperties operator *(VecWithProperties q, VecWithProperties r) {
return new VecWithProperties(q.X * r.X, q.Y * r.Y, q.Z * r.Z);
}
public static VecWithProperties operator +(VecWithProperties q, VecWithProperties r) {
return new VecWithProperties(q.X + r.X, q.Y + r.Y, q.Z + r.Z);
}
}
public readonly struct ReadOnlyVecWithProperties {
public float X { get; }
public float Y { get; }
public float Z { get; }
public ReadOnlyVecWithProperties(float x, float y, float z) {
this.X = x;
this.Y = y;
this.Z = z;
}
public static ReadOnlyVecWithProperties operator *(ReadOnlyVecWithProperties q, ReadOnlyVecWithProperties r) {
return new ReadOnlyVecWithProperties(q.X * r.X, q.Y * r.Y, q.Z * r.Z);
}
public static ReadOnlyVecWithProperties operator +(ReadOnlyVecWithProperties q, ReadOnlyVecWithProperties r) {
return new ReadOnlyVecWithProperties(q.X + r.X, q.Y + r.Y, q.Z + r.Z);
}
}
}
Version 0.7.8 of Inlining Analyzer fails to find many methods with parameters containing readonly references. This is a simple example:
public static int Clamp(in int value, in int min, in int max) => (value < min) ? min : (value > max) ? max : value;
If I remove the in
modifiers, the method gets processed and it works fine. I'm using .NET Framework 4.5 with C# 7.3.
Cannot run this analyzer on several projects, e.g. a public one: https://github.com/Spreads/Spreads.LMDB/
I have only dotnet --version 2.1.402
on my Windows 10 machine (plus full framework 4.7.2).
Haven't found in the docs what dependencies I need to make it work.
Scope: All Types and Methods
Error:
An assembly specified in the application dependencies manifest (JitHost.Core.x64.deps.json) was not found:
package: 'System.Private.ServiceModel', version: '4.5.3'
path: 'runtimes/win/lib/netstandard2.0/System.Private.ServiceModel.dll'
Finished Inlining Analyzer
In the following example:
using System.Runtime.CompilerServices;
namespace ex
{
public struct Cell
{
public int X;
public int Y;
}
public sealed unsafe class CellArray1
{
private Cell* _data;
Cell[] cells;
public CellArray1(int size)
{
cells = new Cell[size];
fixed (Cell* c = &cells[0])
{
_data = c;
}
}
public ref Cell this[int pos]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return ref *(_data + pos); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref Cell At(int pos)
{
return ref *(_data + pos);
}
}
class Program
{
static void Main(string[] args)
{
var m1 = new CellArray1(4096);
var sum1 = 0;
for (var i = 0; i < 4096; i++)
{
m1[i].X = i;
m1.At(i).Y = -1;
sum1 += m1[i].X;
}
}
}
}
I can't get the analyzer to work on the property invocation m1[i]
.
Also I didn't see any annotations when targeting x64 release, and the analysis time seemed slow.
Hi,
I really like your tool. I was looking for that for some while. But I have some strange behavior. Maybe you can explain it.
I have this Employee class in which the call to the Salary (getter) is inlined in the GetYearSalary() method but not in the RaiseSalary() and ToString() methods. The Name (getter) in the ToString() method is also not inlined.
internal class Employee {
public string Name { get; set; }
private double _salary;
public Employee(string name, double salary) {
this.Name = name;
this.Salary = salary;
}
public double GetYearSalary() {
return this.Salary * 12;
}
public double Salary {
get => _salary;
set => _salary = value;
}
public void RaiseSalary(double percentage) {
this.Salary += Salary * (percentage / 100);
}
public override string ToString() {
return string.Format("Employee Name = {0}, Salary = {1}", this.Name, this.Salary.ToString());
}
}
I have moved the Salary property and the Name auto-property to the end of the class and then ran the tool again. The Name and Salary (getters and setters) calls in the GetYearSalary(), RaiseSalary() and ToString() are now all inlined. I find it very strange that the order of the members influences the inlining. Is it a bug? In the compiler or in your extension?
internal class Employee2 {
private double _salary;
public Employee2(string name, double salary) {
this.Name = name;
this.Salary = salary;
}
public double GetYearSalary() {
return this.Salary * 12;
}
public void RaiseSalary(double percentage) {
this.Salary += Salary * (percentage / 100);
}
public override string ToString() {
return string.Format("Employee Name = {0}, Salary = {1}", this.Name, this.Salary.ToString());
}
public double Salary {
get => _salary;
set => _salary = value;
}
public string Name { get; set; }
}
Regards,
Fons
Is this extension supported by Visual Studio 2017? I've tried it on different projects on 2 different machines, but after doing Tools > Inlining Analyzer > Run inlining analyzer on project
, I don't see any calls being highlighted.
I've tried toggling Show/Hide Inlining Analyzer Coloring
, but it doesn't make any difference.
I have ReSharper installed, if it makes any difference. Any idea what could be wrong here? Are there any kind of diagnostic logs that may help?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.