Skip to main content

Performance & Profiling

One runnable Wisej.NET 4 application per module, built from the course's lesson guide, lab guide and walkthrough video. The course is cumulative — every module opens the WisejPerfLab solution of the previous module — so each Module N folder holds the complete application as it stands after module N, and the folder before it is the before for that module's measurements.

WisejPerfLab is a support desk: a dashboard, a ticket grid, a customer tree, a ticket detail form and a CSV export over a seeded dataset of 50,000 tickets and 3,200 customer nodes in a local SQLite file. Module 1 builds it the obvious way and measures it. Module 2 profiles it. Modules 3 to 6 fix one cost bucket each. Module 7 turns the measurements into a capacity model and a health check.

Requirements: the .NET 10 SDK, the Wisej-4 4.1.0 package and Wisej-4-ChartJS 4.1.0, plus EF Core 10.0.12 with the SQLite provider. Nothing is deployed anywhere; the dataset is created on first start (about half a second) and lives in WisejPerfLab/App_Data/.

The modules

ModuleWhat it builds
1 · The Wisej.NET Performance Modelthe application, three named scenarios, ScenarioProbe, the baseline and the budget
2 · Visual Studio Profiling Workflowstages inside each scenario, a call counter, the trace note, the noise floor
3 · CPU Hot Paths and Server-Side UI WorkDashboardSnapshot, aggregates in the database, KPI cards built once
4 · Memory, Allocations and Session LeaksDispose(bool) on the detail form, rows projected once
5 · Data Controls and Large UI Surfacesvirtual grid with a page cache, tree loaded a level at a time
6 · Database, File I/O, Async and Waitsone projection query per page, an index, the export on Application.StartTask
7 · Scale, Health Checks and Final TuningHealthCheck.json, the Capacity screen, the health endpoint, the final report

Run any module from its WisejPerfLab project folder (the projects multi-target net10.0-windows and net10.0):

cd "LearnWisej-Samples/Performance and Profiling Course/Module 3/WisejPerfLab"
dotnet run -c Release -f net10.0 --urls http://localhost:5803

or open WisejPerfLab.slnx in the module folder with Visual Studio and press F5.

Measure in Release. Every number in these folders was taken in Release with no debugger attached, after a discarded warm-up run, as the median of three. The application header says which build it is running under, and says Debug (measure in Release) when it is not.

How to use these samples

Two folders side by side is the whole idea:

# the before
cd "Module 5/WisejPerfLab" && dotnet run -c Release -f net10.0 --urls http://localhost:5805
# the after
cd "Module 6/WisejPerfLab" && dotnet run -c Release -f net10.0 --urls http://localhost:5806

In both: Warm up (discarded run), then Run the three scenarios ×3, then read the medians and the spread the application prints for itself.

The controls

Every module has them, and they are the point rather than decoration:

ControlWhat it is for
Warm up (discarded run)the run nobody records — JIT, the first query plan, the first layout
Run the three scenarios ×3nine runs, three medians, and the spread as a percentage of each median
Break the database / Restorethe failure path: a scenario that fails still reports its elapsed time, and says so on screen
Trace note for the last run (M2+)the note that belongs beside a .diagsession, built from what the app knows
Memory snapshot A / ×50 / Snapshot B (M3+)the leak, as a number: heap, bus subscribers, forms created and disposed
Capacity tab (M7)live readings, the configured thresholds, the model behind them, and what the health URL last answered

What is measured, and what is not

The PERF records measure server handler time — the query, the projection and the control mutation. They do not include serialising the update, sending it or the browser applying it; that is the fifth cost bucket, and Module 5/docs/LargeSurfaces.md explains what could and could not be read for it in a browser where every update travels over the WebSocket.

The database is SQLite, in process. Statement counts are properties of the code and carry over to any database; the milliseconds are flattering, because a statement here costs about 0.05 ms and a statement against a database server costs a network round-trip. Every module README says so where it matters.