dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.84k stars 4.62k forks source link

Performance profiling for WebAssembly #76316

Open SteveSandersonMS opened 3 years ago

SteveSandersonMS commented 3 years ago

Tentative goals

Related https://github.com/dotnet/runtime/issues/69268

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

ghost commented 3 years ago

Thanks for contacting us. We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Stamo-Gochev commented 3 years ago

@SteveSandersonMS Can you share more information where this profiler can be found? I see that it is internal, but I can try to rebuild the source code on my side to expose it in some way as I want to debug a wasm app for performance reasons. I have no expectations for it to be working as you mentioned it is targeting 6.0 or later, but I can give it a try for testing purposes.

Stamo-Gochev commented 3 years ago

@SteveSandersonMS Any updates?

SteveSandersonMS commented 3 years ago

The experimental code we used is in https://github.com/dotnet/runtime/tree/stevesa/hierarchical-profile, however it's not intended for external use, hence there's no information about how to build or use it, or how to understand any data it collects, and it most likely no longer works with current builds of the runtime.

szalapski commented 3 years ago

Would like to see a way to profile Blazor on the client, with an eye toward optimizing performance. Main scenario: I just clicked on an item and it worked 20 seconds before I can see the new UI, and I am quite certain it is not due to download time/network latency; what's taking so long that I should try to optimize?

ghost commented 3 years ago

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

jirisykora83 commented 2 years ago

@SteveSandersonMS Any updates?

jirisykora83 commented 2 years ago

Would like to see a way to profile Blazor on the client, with an eye toward optimizing performance. Main scenario: I just clicked on an item and it worked 20 seconds before I could see the new UI, and I am quite certain it is not due to download time/network latency; what's taking so long that I should try to optimize?

I face similar issue and one workround is create BaseComponent add it to _Imports.razor as base class for every component @inherits XXX.BaseComponent and then use component live cycle with https://developer.mozilla.org/en-US/docs/Web/API/console/time this give me at least some insight.

This is inspired by https://remibou.github.io/Profiling-in-Blazor/

console.time produce some sort of flamegraph in chrome. This is nowhere near the dev experience with full .NET profiler of course.

MertUssakliMSFT commented 2 years ago

If there was at least a way to relate compiled wasm-functionss you see in the Edge profiler back to .NET code symbols, that would be a huge step forward! I can profile and see CPU-heavy workload causing UI delays, but it is impossible to debug it back to what part of the code would need optimization.

image
Chris-D-Turk commented 2 years ago

@MertUssakliMSFT you can actually see the real method-names if you enable AOT compilation in your csproj:

    <RunAOTCompilation>true</RunAOTCompilation>
    <RunAOTCompilationAfterBuild>true</RunAOTCompilationAfterBuild>
    <WasmNativeStrip>false</WasmNativeStrip>

But the build takes a very long time with this config - ~10min for a new blazor wasm solution on my machine. Maybe you can speed up the build, if your strip unused assemblies - but I don't know how to do this.

MertUssakliMSFT commented 2 years ago

@Chris-D-Turk, cool tip -- will keep this in mind the next time I need to do perf profiling.

Does it work in Release/Ship as well as Debug?

Chris-D-Turk commented 2 years ago

@MertUssakliMSFT yes, it works for both debug and release builds

zHaytam commented 1 year ago

Any news about this?

ghost commented 1 year ago

Tagging subscribers to this area: @tommcdon See info in area-owners.md if you want to be subscribed.

Issue Details
In 5.0 we implemented an internal prototype of profile capture for `dotnet.wasm`. Let's look at making this into part of the product for 6.0.
Author: SteveSandersonMS
Assignees: -
Labels: `area-Diagnostics-coreclr`
Milestone: -
mkArtakMSFT commented 1 year ago

@lewing let's include this in an agenda for our weekly sync meetings. We'd like to have something for customers here in .NET 8.

ghost commented 1 year ago

Tagging subscribers to 'arch-wasm': @lewing See info in area-owners.md if you want to be subscribed.

Issue Details
In 5.0 we implemented an internal prototype of profile capture for `dotnet.wasm`. Let's look at making this into part of the product for 6.0.
Author: SteveSandersonMS
Assignees: pavelsavara, radekdoulik
Labels: `arch-wasm`, `area-Diagnostics-coreclr`, `arm64`
Milestone: 8.0.0
pavelsavara commented 1 year ago

@SteveSandersonMS where do I find the old prototype ?

SteveSandersonMS commented 1 year ago

@pavelsavara I dug up some info in an old email thread and am forwarding it to you.

pavelsavara commented 1 year ago

Notes to self https://github.com/dotnet/runtime/pull/70851

dotnet-trace collect --providers Microsoft-Windows-DotNETRuntime:0x1F000080018:5

https://github.com/dotnet/runtime/blob/fb104e374d89f3e005e6d67fc7766e824f88dd11/src/coreclr/vm/ClrEtwAll.man#L14-L92

https://github.com/dotnet/runtime/blob/fb104e374d89f3e005e6d67fc7766e824f88dd11/src/mono/mono/eventpipe/ep-rt-mono.c#L220-L240

jjzhang12 commented 1 year ago

@pavelsavara : How can I enable the browserProfilerOptions of https://github.com/dotnet/runtime/pull/77449 in Blazor WebAssembly?

pavelsavara commented 1 year ago

@jjzhang12 with latest previews you can use new API configureRuntime which allows you to configure runtime. I tested with 8.0.0-rc.1.23402.3 wasm-tools workload installed.

In your project file <WasmProfilers>browser;</WasmProfilers><WasmBuildNative>true</WasmBuildNative> And in your index.html

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
Blazor.start({
    configureRuntime: function (builder) {
        builder.withConfig({
            browserProfilerOptions: {}
        });
    }
});
</script>
jjzhang12 commented 1 year ago

@pavelsavara Thanks, I installed the latest .net 8 preview 7 and implemented the above change to the template sample app, I still see "wasm-functions[]" in performance profile. I tried debug, release, published and published with AOT, all same result. I saw you are using rc version (8.0.0-rc.1.23402.3), how can I get that wasm-tools?

pavelsavara commented 1 year ago

I still see "wasm-functions[]" in performance profile.

Those are C symbols of the mono VM. You can enable them by <WasmNativeDebugSymbols>true</WasmNativeDebugSymbols><WasmNativeStrip>false</WasmNativeStrip>

Note that is being improved right now https://github.com/dotnet/runtime/pull/89754

I saw you are using rc version (8.0.0-rc.1.23402.3), how can I get that wasm-tools?

Wait for next preview to be released or use nightly build https://aka.ms/dotnet/8.0.1xx/daily/dotnet-sdk-win-x64.zip

jjzhang12 commented 1 year ago

@pavelsavara Thank you very much. Adding those two flags works perfectly. Now waiting for the full performance porfiler to be released:-)

ts-indikaf commented 11 months ago

@jjzhang12 with latest previews you can use new API configureRuntime which allows you to configure runtime. I tested with 8.0.0-rc.1.23402.3 wasm-tools workload installed.

In your project file <WasmProfilers>browser;</WasmProfilers><WasmBuildNative>true</WasmBuildNative> And in your index.html

<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
Blazor.start({
    configureRuntime: function (builder) {
        builder.withConfig({
            browserProfilerOptions: {}
        });
    }
});
</script>

@pavelsavara Is there a solution for pure WebAssembly projects?

pavelsavara commented 11 months ago

<WasmProfilers>browser;</WasmProfilers><WasmBuildNative>true</WasmBuildNative>

import { dotnet } from './dotnet.js'
const runtime  = dotnet
        .withConfig({
            browserProfilerOptions: {}
        })
        .create()
;
ts-indikaf commented 11 months ago

@pavelsavara thanks - it works.

jjzhang12 commented 10 months ago

@pavelsavara : I can profile my app in Preview 7. But for the same Blazor app in rc2, if I turn on those flags, the page goes out of memory quickly. I did look at the task bar and saw the Edge used more than 4GB memory before the page crashes. Without the profile flags, the memory is about 350MB.

I still can profile a simple app though.

Do we have option to reduce the memory consumption of this profile feature? I mean, back to preview 7 level for example.

pavelsavara commented 10 months ago

This is logging, not sampling profiler and so it collects everything. (besides memory it also consumes CPU and affects timing). I'm not aware of any recent changes to profiler which would cause more calls to be reported.

Maybe some you have some build flags which make this to generate more methods or more calls in the profiled code ?

ts-indikaf commented 10 months ago

@pavelsavara thanks - it works.

@pavelsavara Unfortunately, this only works with the sample DotNet project not with my real Wasm app. Chrome Profile loading goes forever with the real app. I'm using .DotNet8 RC1.

MattParkerDev commented 9 months ago

@pavelsavara How much effort is involved in adding method filtering to #77449?

pavelsavara commented 9 months ago

@pavelsavara How much effort is involved in adding method filtering to #77449?

It would be good to filter in early on Mono side, probably here https://github.com/dotnet/runtime/blob/f39dae85e28de85f87bb921a9e6a6581d531d293/src/mono/mono/profiler/browser.c#L70

Similar to https://github.com/dotnet/runtime/blob/f39dae85e28de85f87bb921a9e6a6581d531d293/src/mono/mono/profiler/log.c#L1974-L1976

And you need to pass the configuration flags this is how other mono profilers do it https://github.com/dotnet/runtime/blob/f39dae85e28de85f87bb921a9e6a6581d531d293/src/mono/mono/profiler/coverage.c#L1053

I'm not sure this is best way how to do it together with JavaScript. I would prefer to make it work with browserProfilerOptions

ocoka commented 8 months ago

Hello for community !

I am interested in profiling my project and have read the whole discussion, but I still don't understand clearly:

  1. What exactly are the minimum parameters I need in a .csproj file ?
  2. Can this be used with dotnet run ?
  3. Does there have to be a Release configuration ?
  4. and what is the purpose of the expression in Blazor index.html:
    Blazor.start({
            configureRuntime: function (builder) {
                builder.withConfig({
                    browserProfilerOptions: {}
                });
            }
        });

    I tested the solution on .NET8, done with dotnet publish -c Debug, and served from Nginx, and having in the .csproj configuration:

    <RunAOTCompilation>true</RunAOTCompilation>.
    <RunAOTCompilationAfterBuild>true</RunAOTCompilationAfterBuild>
    <WasmNativeStrip>false</WasmNativeStrip>
    <WasmProfilers>browser;</WasmProfilers>
    <WasmBuildNative>true</WasmBuildNative>

This does crash in Google Chrome with a SIGILL signal, but Firefox survives and profiling works. Maybe I don't need the whole list of above parameters anymore since I have .NET8 ?

tibuprophen commented 4 months ago

Hi! I am also having some trouble enabling profiling on WASM. May someone clear it up how to set up profiling properly? I achived chrome profiling on a fresh web project with changes @ocoka posted. Is there any option without AOT complilation and publishing the project?