What Is SamplingProfiler for Delphi and How Do You Use It to Find Bottlenecks?
SamplingProfiler is a free code profiler for Delphi and other Pascal toolchains, distributed from DelphiTools.info alongside DWScript (Delphi Web Script) and related Pascal developer tools. It finds bottlenecks by statistical sampling: it periodically captures the call stack of a running application and aggregates those snapshots into per-routine sample counts, so the routines that appear most often are the ones consuming the most execution time. Use it when you have a compiled Delphi application that feels slow and you want to know where the time goes without adding timing code to every routine.
What SamplingProfiler is
DelphiTools.info describes itself as the home of SamplingProfiler, "a free code profiler for Delphi, DWScript (Delphi Web Script) and other Pascal developer tools," alongside optimization and coding tips. The site also hosts DWScript and other Pascal tools, and its news covers adjacent developer utilities such as a fork of DelphiCodeCoverage with AI-oriented reporting formats.
Two consequences follow from that positioning:
- It is a sampling profiler, not an instrumenting one. You do not modify your source to insert timers or counters.
- It targets Delphi and Pascal code, including scripted Pascal through DWScript, rather than being a general-purpose profiler for arbitrary languages.
How statistical sampling locates hot code
A sampling profiler does not measure every call. Instead it interrupts the process at intervals, walks the current call stack, and records which routine is on top (and often the full chain of callers). After thousands of samples, the distribution of samples across routines approximates the distribution of time across routines.
The practical implications:
| Property | What it means for you |
|---|---|
| No source instrumentation | You can profile a build you already have, as long as symbols are available |
| Statistical, not exact | Results are approximate; short runs give noisy rankings |
| Stack-based | You see call paths, not just flat totals, so you can tell who called the hot routine |
| Low overhead relative to instrumentation | The app keeps running close to normal speed, which matters for interactive or I/O-heavy code |
The routine with the largest share of samples is your first bottleneck candidate. If a routine is hot but only ever called from one place, the fix may belong in the caller; if it is called from many places, the routine itself is the target.
Using it to find bottlenecks
The general workflow, which applies to SamplingProfiler and to sampling profilers in this family:
- Build with debug information. Compile the application so that routine names and line information are available. Without symbols, samples collapse into addresses and the profile is unreadable.
- Reproduce the slow scenario. Start the application and drive it into the state you care about — load the large file, run the heavy calculation, open the slow form. Profiling an idle app tells you nothing.
- Attach the profiler and start sampling. Point SamplingProfiler at the running process and begin a session. Let the scenario run long enough to accumulate a meaningful number of samples; a few seconds of activity is usually too few.
- Stop and read the results. Sort by sample count or by self time. Identify the top routines and, using the call graph, trace which paths reach them.
- Fix and re-measure. Change one thing, re-run the same scenario, and compare. Sampling noise means you should look for large, repeatable shifts rather than small deltas.
The expected result at each step: after step 3 you have a sample set; after step 4 you have a ranked list of routines and their callers; after step 5 you have evidence that your change actually moved the bottleneck rather than just moving it elsewhere.
Common pitfalls
- Missing debug symbols. The most common reason a profile looks like a wall of addresses. Rebuild with debug info before profiling.
- Optimization settings. Aggressive optimization can inline routines, so a hot routine may be attributed to its caller. Treat inlined results as a hint about the call site, not a precise per-routine measurement.
- Runs that are too short. Sampling needs volume. A scenario that finishes in a fraction of a second may produce too few samples to rank reliably; loop it or extend it.
- Profiling the wrong scenario. If the app is slow only under a specific input or after a specific sequence of actions, reproduce exactly that, or you will optimize code that was never the problem.
- Chasing the top entry blindly. A routine high in the list may be a dispatcher or framework call that is simply on every path. Look at self time and at whether the routine does real work.
Where it fits among Delphi tools
DelphiTools.info groups SamplingProfiler with DWScript and other Pascal developer tools, and its news stream covers related utilities such as the AI-optimized DelphiCodeCoverage report format. If your goal is coverage rather than timing, that is a different tool; if your goal is to know where execution time is spent in a running Delphi or Pascal application, SamplingProfiler is the one to reach for. The site does not state pricing on the material available here beyond describing the profiler as free, so treat any licensing or version-support question as something to confirm on the site itself.