Does Jetbrains Rider have Function like View disassembly code in the Visual Studio debugger
Asked Answered
I

1

6

Visual studio 2019 supports a Function named 'View disassembly code in the Visual Studio debugger'. But I want to use 'View disassembly code in debugger' in Rider, not in visual studio 2019.

Can I do this?

I could find 'IL View', but that's not what I think.

Illustrate answered 28/3, 2021 at 16:35 Comment(4)
Do you really want the X64 assembly (which is typically quite useless for managed code) or the IL?Anglophobe
I want x64 assembly. Because my purpose is studying difference between debug build and release build, not managing code.Illustrate
I can't answer your question (since I've not worked with Rider yet), but for managed code, you'll probably not get the insight you expect when looking at the x64 code difference between debug and release, since that's mostly caused by the compiler, not the jit (the later doesn't know whether the code is debug or release). If you want to learn about optimizations, you should look at the IL difference instead - much easier to read, by the way.Anglophobe
Viewing IL is mostly useless for gauging the quality of the machine code. Performance killers like mandatory bounds checking aren't even visible at that level, and it is impossible fathom why e.g. the .NET Framework JIT compiler manages to hoist the bounds check out of a critical loop whereas the JIT compilers of later editions (e.g. .NET 5, .NET 6) lost that ability.Elohist
E
4

While we're waiting for Rider to maybe/hopefully integrate this functionality, here is one option that is in some regards even better than Microsoft's offering: the combined decompilation, IL and native disassembly view of newer LINQPad versions. I use both Rider and LINQPad all the time and they complement each other nicely.

Here's how I just verified that the cost of abstraction for a readonly struct that wraps an Int64 is indeed zero as I had hoped:

combined decompilation, IL and native disassembly view (click to enlarge if necessary)

The upper pane shows the source code with a nested for loop which repeatedly calls a static method on BT.ERezeptId and stuffs the result into an array.

The decompilation pane (left) shows that the compiler has effectively converted the for loops into equivalent while loops.

I have focussed the IL pane (middle) only on the inner loop because in IL the loop setup and the outer loop add a lot of lines that are all boring.

The native code pane (right) shows that the compiler has cut through quite a lot of fluff when it optimised the IL. It has effectively inlined/flattened calls that are several layers deep on the source code level, thus eliminating all abstraction cost. The code is just as efficient as if it were dealing with naked Int64 instead of a struct that wraps one.

This is most immediately apparent from the fact that the method called on the source code level is zufaellig() whereas the method called in the native code is Zufallswert(). In fact, the compiler only stopped inlining at that point because I ordered it to do so!

Here are the layers of abstraction onion that got eliminated (all of which resides in a referenced assembly, not in the current source file):

public readonly partial struct ERezeptId
{
    private readonly long m_Wert;

    public ERezeptId (Ungeprueft<long> ungeprueft)
    {
        m_Wert = ungeprueft.Wert;
    }

    // ...

    public static ERezeptId zufaellig (Random rng)
    {
        return new ERezeptId(new Ungeprueft<long>(Zufallswert(rng)));
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static long Zufallswert (Random rng)
    {
        // ...
    }
}

public readonly struct Ungeprueft<T>
{
    public readonly T Wert;

    public Ungeprueft (T wert)
    {
        Wert = wert;
    }
}

NB: the Ungeprueft<> thing (German for 'unchecked') is a standard template of mine that makes it explicit when parameter validation is bypassed intentionally.

Note: this answer doesn't show how to view the disassembly in Rider - which is what the OP asked - because that functionality is not yet available in Rider. However, LINQPad can be a useful thing to have for any user of Rider, or any .NET programmer for that matter. In fact, if push came to shove I could maybe - with lots of cussing and loss of productivity! - use another IDE instead of Rider but it would be impossible for me to work effectively without LINQPad ...

Elohist answered 18/12, 2022 at 14:9 Comment(1)
although this is old question, thank you for useful answeringIllustrate

© 2022 - 2024 — McMap. All rights reserved.