protected override void OnProfilingFinished(BaseProfilerResult <ProfilerCategory> result) { var frameMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.Frame, 0); var lockMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.Lock, 0); var updateMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.Update, 0); var updateNetworkMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateNetwork, 0); var updateReplMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateReplication, 0); var updateSessionCompsMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateSessionComponents, 0); var updateSessionCompsAllMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateSessionComponentsAll, 0); var updateSessionCompsOtherMs = updateSessionCompsAllMs - updateSessionCompsMs; var updateGpsMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateGps, 0); var updateParallelWaitMs = (float)result.GetMainThreadTickMsOrElse(ProfilerCategory.UpdateParallelWait, 0); var updateOtherMs = updateMs - updateNetworkMs - updateReplMs - updateSessionCompsAllMs - updateGpsMs - updateParallelWaitMs; TorchInfluxDbWriter .Measurement("profiler_game_loop") .Field("frame", frameMs / result.TotalFrameCount) .Field("wait", lockMs / result.TotalFrameCount) .Field("update", updateMs / result.TotalFrameCount) .Field("update_network", updateNetworkMs / result.TotalFrameCount) .Field("update_replication", updateReplMs / result.TotalFrameCount) .Field("update_session_components", updateSessionCompsMs / result.TotalFrameCount) .Field("update_session_components_all", updateSessionCompsAllMs / result.TotalFrameCount) .Field("update_session_components_other", updateSessionCompsOtherMs / result.TotalFrameCount) .Field("update_gps", updateGpsMs / result.TotalFrameCount) .Field("update_parallel_wait", updateParallelWaitMs / result.TotalFrameCount) .Field("update_other", updateOtherMs / result.TotalFrameCount) .Write(); }
protected override void OnProfilingFinished(BaseProfilerResult <IMyFaction> result) { // get online players per faction var onlineFactions = new Dictionary <string, int>(); var onlinePlayers = MySession.Static.Players.GetOnlinePlayers(); foreach (var onlinePlayer in onlinePlayers) { var faction = MySession.Static.Factions.TryGetPlayerFaction(onlinePlayer.PlayerId()); if (faction == null) { continue; } onlineFactions.Increment(faction.Tag); } foreach (var(faction, entity) in result.GetTopEntities()) { onlineFactions.TryGetValue(faction.Tag, out var onlinePlayerCount); onlinePlayerCount = Math.Max(1, onlinePlayerCount); // fix zero division var mainMs = entity.MainThreadTime / result.TotalFrameCount; var mainMsPerMember = mainMs / onlinePlayerCount; TorchInfluxDbWriter .Measurement("profiler_factions") .Tag("faction_tag", faction.Tag) .Field("main_ms", mainMs) .Field("main_ms_per_member", mainMsPerMember) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <Type> result) { foreach (var(type, entry) in result.GetTopEntities(MaxDisplayCount)) { TorchInfluxDbWriter .Measurement("profiler_block_types") .Tag("block_type", type.Name) .Field("main_ms", (float)entry.MainThreadTime / result.TotalFrameCount) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <MyCubeGrid> result) { foreach (var(grid, entity) in result.GetTopEntities(MaxDisplayCount)) { TorchInfluxDbWriter .Measurement("profiler") .Tag("grid_name", GridToResultText(grid)) .Field("main_ms", (float)entity.MainThreadTime / result.TotalFrameCount) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <string> result) { foreach (var(name, entity) in result.GetTopEntities()) { TorchInfluxDbWriter .Measurement("profiler_method_names") .Tag("method_name", name) .Field("ms", (float)entity.MainThreadTime / result.TotalFrameCount) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <string> result) { foreach (var(methodName, entry) in result.GetTopEntities()) { var eventName = methodName.Split('#')[1]; TorchInfluxDbWriter .Measurement("profiler_network_events") .Tag("site_name", eventName) .Field("main_ms", (float)entry.MainThreadTime / result.TotalFrameCount) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <MyIdentity> result) { foreach (var(player, entity) in result.GetTopEntities(10)) { var playerName = player.DisplayName; var steamId = MySession.Static.Players.TryGetSteamId(player.IdentityId); playerName = _nameConflictSolver.GetSafeName(playerName, steamId); var mainMs = entity.MainThreadTime / result.TotalFrameCount; TorchInfluxDbWriter .Measurement("profiler_players") .Tag("player_name", playerName) .Field("main_ms", mainMs) .Write(); } }
protected override void OnProfilingFinished(BaseProfilerResult <MySessionComponentBase> result) { foreach (var(comp, entity) in result.GetTopEntities()) { var ms = (float)entity.MainThreadTime / result.TotalFrameCount; var type = comp.GetType(); var name = _myConfig.MonitorSessionComponentNamespace ? $"{type.Namespace}/{type.Name}" : type.Name; TorchInfluxDbWriter .Measurement("profiler_game_loop_session_components") .Tag("comp_name", name) .Field("main_ms", ms) .Write(); } }
public void Update(BaseProfilerResult <MyIdentity> profileResult) { Log.Trace("updating player lags..."); var results = new List <EntitySource>(); foreach (var(player, profilerEntry) in profileResult.GetTopEntities(20)) { var mspf = profilerEntry.MainThreadTime / profileResult.TotalFrameCount; var faction = MySession.Static.Factions.TryGetPlayerFaction(player.IdentityId); var factionId = faction?.FactionId ?? 0L; var factionTag = faction?.Tag ?? "<single>"; var result = new EntitySource(player.IdentityId, player.DisplayName, player.IdentityId, player.DisplayName, factionId, factionTag, mspf); results.Add(result); } _entityTracker.Update(results); Log.Trace("updated player lags"); }
protected override void OnProfilingFinished(BaseProfilerResult <MyProgrammableBlock> result) { foreach (var(pb, entity) in result.GetTopEntities(MaxDisplayCount)) { var grid = pb?.GetParentEntityOfType <MyCubeGrid>(); if (grid == null) { return; } var gridName = _nameConflictSolver.GetSafeName(grid.DisplayName, grid.EntityId); var mainMs = (float)entity.MainThreadTime / result.TotalFrameCount; TorchInfluxDbWriter .Measurement("profiler_scripts") .Tag("grid_name", gridName) .Field("main_ms", mainMs) .Write(); } }
void ProcessResult(BaseProfilerResult <HkWorld> result) { foreach (var(world, entity) in result.GetTopEntities(_physicsConfig.PhysicsMaxClusterCount)) { // this usually doesn't happen but just in case if (!TryGetHeaviestGrid(world, out var heaviestGrid)) { continue; } heaviestGrid.BigOwners.TryGetFirst(out var ownerId); var faction = MySession.Static.Factions.GetPlayerFaction(ownerId); var factionTag = faction?.Tag ?? "<n/a>"; var gridName = heaviestGrid.DisplayName.OrNull() ?? "<no name>"; var mainMs = entity.MainThreadTime / result.TotalFrameCount; TorchInfluxDbWriter .Measurement("profiler_physics_grids") .Tag("grid", $"[{factionTag}] {gridName}") .Field("main_ms", mainMs) .Write(); } }
protected abstract void OnProfilingFinished(BaseProfilerResult <T> result);
private void OnProfilerRequestFinished(BaseProfilerResult <MyCubeGrid> result, ulong ticks) { var measureResults = result.MapKeys(myCubeGrid => MyCubeGridGroups.Static.Logical.GetGroupNodes(myCubeGrid).MaxBy(it => it.BlocksPCU) ).GetTopEntities() .Where(it => it.Entity.MainThreadTime != 0) .Select(it => new MeasureResult(it.Key, it.Entity, ticks)) .Where(it => it.PlayerIdentityId != 0) .OrderByDescending(it => it.MainThreadTimePerTick) .ToList(); var entityIdToResult = measureResults.ToDictionary(it => it.EntityId, it => it); Plugin.LatestResults = entityIdToResult; var now = DateTime.UtcNow; Plugin.LatestMeasureTime = now; //write to file if (Config.WriteToFile) { var resultFileName = Config.ResultFileName; if (resultFileName.Length == 0) { resultFileName = LagGridBroadcasterConfig.ResultFileDefaultName; } new Persistent <MeasureResultsAndTime>( Path.Combine(Plugin.StoragePath, resultFileName), new MeasureResultsAndTime(measureResults, now) ).Save(); Log.Info("Measure results saved to file"); } //global top x grids var noOutputWhileEmptyResult = Config.NoOutputWhileEmptyResult; var top = (int)Config.Top; if (top != 0) { var minMs = Config.MinMs; var minUs = Config.MinUs; var factionMemberDistance = Config.FactionMemberDistance; var globalTopResults = measureResults.Where(it => it.MainThreadTimePerTick >= minMs) .Where(measureResult => { if (factionMemberDistance == 0) { return(true); } //any faction member close to this grid var factionMembers = measureResult.FactionId == null ? new List <MyPlayer> { GetPlayerById(measureResult.PlayerIdentityId) } : MySession.Static.Factions[measureResult.FactionId.Value].Members.Keys .Select(GetPlayerById); return(factionMembers.Where(it => it != null).Any(it => //only online faction member Vector3.Distance(measureResult.EntityCoords, it.GetPosition()) <= factionMemberDistance )); }) .Take(top) .ToList(); if (globalTopResults.Count != 0 || !noOutputWhileEmptyResult) { // ReSharper disable once UseStringInterpolation SendMessage(string.Format("Global top {0} grids{1}:", globalTopResults.Count == top ? top.ToString() : $"{globalTopResults.Count}/{Config.Top}", minUs == 0 ? "" : $"(over {minUs}us)" )); globalTopResults.ForEach(it => { //send chat message to all player SendMessage(FormatResult(it)); //send gps to all players Broadcast(it); }); } } //send factionTop to faction members var factionTop = (int)Config.FactionTop; if (factionTop != 0) { var playerIdentityIdToResult = new Dictionary <long, List <MeasureResult> >(); var factionIdToResult = new Dictionary <long, List <MeasureResult> >(); measureResults.ForEach(it => { if (it.FactionId == null) { playerIdentityIdToResult.AddOrUpdateList(it.PlayerIdentityId, it); } else { factionIdToResult.AddOrUpdateList(it.FactionId.Value, it); } }); MySession.Static.Players.GetOnlinePlayers() .Where(it => it.IsRealPlayer) .ForEach(player => { var playerIdentityId = player.Identity.IdentityId; var faction = MySession.Static.Factions.GetPlayerFaction(playerIdentityId); IEnumerable <MeasureResult> factionTopResultsEnumerable; if (faction == null) //player not join faction { factionTopResultsEnumerable = playerIdentityIdToResult.GetValueOrDefault(playerIdentityId) ?.Take(factionTop); } else { factionTopResultsEnumerable = factionIdToResult.GetValueOrDefault(faction.FactionId) ?.Take(factionTop); } var factionTopResults = factionTopResultsEnumerable?.ToList() ?? new List <MeasureResult>(); if (factionTopResults.Count == 0 && noOutputWhileEmptyResult) { return; } var playerSteamId = player.Id.SteamId; // ReSharper disable once UseStringInterpolation SendMessage(string.Format("Faction top {0} grids:", factionTopResults.Count < factionTop ? $"{factionTopResults.Count}/{factionTop}" : factionTop.ToString() ), playerSteamId); factionTopResults.ForEach(it => SendMessage(FormatResult(it), playerSteamId) ); }); } //send result of controlling grid to player if (Config.SendResultOfControllingGrid) { MySession.Static.Players.GetOnlinePlayers() .Where(it => it.IsRealPlayer) .ForEach(player => { var entity = player?.Controller?.ControlledEntity?.Entity; if (entity == null) { return; } if (!TryGetControllingGrid(entity, out var grid)) { return; } var measureResult = entityIdToResult.GetValueOrDefault(grid.EntityId); if (measureResult == null) { return; } SendMessage( $"Your current controlling grid '{measureResult.EntityDisplayName}' took {FormatTime(measureResult.MainThreadTimePerTick)}", player.Id.SteamId ); }); } }