SwiftlyS2
Development

Profiler

SwiftlyS2 provides a profiler service for measuring execution time in plugin code and recording custom duration metrics.

Accessing Profiler Service

The profiler service is available through Core.Profiler.

public override void Load(bool hotReload)
{
    var profiler = Core.Profiler;
}

Measuring Code Blocks

Start/Stop Recording

Use StartRecording(name) and StopRecording(name) with the same profile name.

Core.Profiler.StartRecording("MyOperation");

PerformSomeOperation();

Core.Profiler.StopRecording("MyOperation");

Safe Pairing with try/finally

To avoid mismatched recordings when exceptions happen, pair start/stop in try/finally.

Core.Profiler.StartRecording("Database.PlayerStats.Load");
try
{
    LoadPlayerStats();
}
finally
{
    Core.Profiler.StopRecording("Database.PlayerStats.Load");
}

Recording Precomputed Durations

Use RecordTime(name, duration) when you already measured a duration yourself.

var stopwatch = System.Diagnostics.Stopwatch.StartNew();

BuildLargeMenu();

stopwatch.Stop();
double durationUs = stopwatch.ElapsedTicks * (1_000_000.0 / System.Diagnostics.Stopwatch.Frequency);
Core.Profiler.RecordTime("Menu.Build", durationUs);

RecordTime accepts double. Use microseconds for durations so profiler entries stay consistent.

Profiling Sub-Operations

Profile major flow steps separately to find hot spots faster.

public void ProcessPlayerData(IPlayer player)
{
    Core.Profiler.StartRecording("PlayerData.Process");
    try
    {
        Core.Profiler.StartRecording("PlayerData.Load");
        try
        {
            LoadPlayerData(player.SteamID);
        }
        finally
        {
            Core.Profiler.StopRecording("PlayerData.Load");
        }

        Core.Profiler.StartRecording("PlayerData.Apply");
        try
        {
            ApplyPlayerData(player);
        }
        finally
        {
            Core.Profiler.StopRecording("PlayerData.Apply");
        }
    }
    finally
    {
        Core.Profiler.StopRecording("PlayerData.Process");
    }
}

Naming Strategy

Use clear, hierarchical names so related entries group naturally.

category.operation.detail

Examples:

  • Database.Players.Load
  • Database.Players.Save
  • Menu.Main.Build
  • Menu.Main.Open
  • Commands.Teleport.Execute
  • Events.PlayerSpawn.Process

Avoid overly generic names such as Operation or Process.

Reference

See IContextedProfilerService for full API details.

On this page