minor performance improvements

This commit is contained in:
rootdarkarchon
2024-02-12 17:02:49 +01:00
parent 09790553c3
commit 6685139caf
4 changed files with 200 additions and 186 deletions

View File

@@ -1,4 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.Game.Character; using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using MareSynchronos.Services; using MareSynchronos.Services;
using MareSynchronos.Services.Mediator; using MareSynchronos.Services.Mediator;
@@ -209,7 +210,7 @@ public sealed class GameObjectHandler : DisposableMediatorSubscriberBase
_clearCts = null; _clearCts = null;
} }
var chara = (Character*)Address; var chara = (Character*)Address;
var name = new ByteString(chara->GameObject.Name).ToString(); MemoryHelper.ReadStringNullTerminated((nint)chara->GameObject.Name, out var name);
bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal); bool nameChange = !string.Equals(name, Name, StringComparison.Ordinal);
if (nameChange) if (nameChange)
{ {

View File

@@ -1,6 +1,7 @@
using Dalamud.Game.ClientState.Conditions; using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Objects; using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.SubKinds; using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Memory;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Control; using FFXIVClientStructs.FFXIV.Client.Game.Control;
@@ -362,8 +363,6 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
} }
private unsafe void CheckCharacterForDrawing(nint address, string characterName) private unsafe void CheckCharacterForDrawing(nint address, string characterName)
{
if (!IsAnythingDrawing)
{ {
var gameObj = (GameObject*)address; var gameObj = (GameObject*)address;
var drawObj = gameObj->DrawObject; var drawObj = gameObj->DrawObject;
@@ -417,7 +416,6 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
IsAnythingDrawing |= isDrawing; IsAnythingDrawing |= isDrawing;
} }
}
private void FrameworkOnUpdate(IFramework framework) private void FrameworkOnUpdate(IFramework framework)
{ {
@@ -431,17 +429,23 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
return; return;
} }
bool isNormalFrameworkUpdate = DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1);
_performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal+" + (isNormalFrameworkUpdate ? "Regular" : "Delayed"), () =>
{
IsAnythingDrawing = false; IsAnythingDrawing = false;
_performanceCollector.LogPerformance(this, "ObjTableToCharas", _performanceCollector.LogPerformance(this, "ObjTableToCharas",
() => () =>
{ {
_notUpdatedCharas.AddRange(_playerCharas.Keys); _notUpdatedCharas.AddRange(_playerCharas.Keys);
foreach (var chara in _objectTable) for (int i = 0; i < 200; i += 2)
{ {
if (chara.ObjectIndex % 2 != 0 || chara.ObjectIndex >= 200) continue; var chara = _objectTable[i];
if (chara == null || chara.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player)
continue;
string charaName = chara.Name.ToString(); MemoryHelper.ReadStringNullTerminated((nint)((GameObject*)chara.Address)->Name, out string charaName);
string homeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld.ToString(); string homeWorldId = ((BattleChara*)chara.Address)->Character.HomeWorld.ToString();
var hash = (charaName + homeWorldId).GetHash256(); var hash = (charaName + homeWorldId).GetHash256();
@@ -509,7 +513,11 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
Mediator.Publish(new ResumeScanMessage(nameof(IsInCutscene))); Mediator.Publish(new ResumeScanMessage(nameof(IsInCutscene)));
} }
if (IsInCutscene) { Mediator.Publish(new CutsceneFrameworkUpdateMessage()); return; } if (IsInCutscene)
{
Mediator.Publish(new CutsceneFrameworkUpdateMessage());
return;
}
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51]) if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51])
{ {
@@ -538,11 +546,13 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
} }
if (!IsInCombatOrPerforming) if (!IsInCombatOrPerforming)
Mediator.Publish(new FrameworkUpdateMessage()); _performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal>MediatorFrameworkUpdate",
() => Mediator.Publish(new FrameworkUpdateMessage()));
Mediator.Publish(new PriorityFrameworkUpdateMessage()); Mediator.Publish(new PriorityFrameworkUpdateMessage());
if (DateTime.Now < _delayedFrameworkUpdateCheck.AddSeconds(1)) return; if (isNormalFrameworkUpdate)
return;
var localPlayer = _clientState.LocalPlayer; var localPlayer = _clientState.LocalPlayer;
@@ -561,10 +571,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
} }
if (IsInCombatOrPerforming) if (IsInCombatOrPerforming)
Mediator.Publish(new FrameworkUpdateMessage()); _performanceCollector.LogPerformance(this, "FrameworkOnUpdateInternal>MediatorFrameworkUpdate",
() => Mediator.Publish(new FrameworkUpdateMessage()));
Mediator.Publish(new DelayedFrameworkUpdateMessage()); Mediator.Publish(new DelayedFrameworkUpdateMessage());
_delayedFrameworkUpdateCheck = DateTime.Now; _delayedFrameworkUpdateCheck = DateTime.Now;
});
} }
} }

View File

@@ -130,40 +130,43 @@ public sealed class MareMediator : IHostedService
{ {
if (!_subscriberDict.TryGetValue(message.GetType(), out HashSet<SubscriberAction>? subscribers) || subscribers == null || !subscribers.Any()) return; if (!_subscriberDict.TryGetValue(message.GetType(), out HashSet<SubscriberAction>? subscribers) || subscribers == null || !subscribers.Any()) return;
HashSet<SubscriberAction> subscribersCopy = []; List<SubscriberAction> subscribersCopy = [];
lock (_addRemoveLock) lock (_addRemoveLock)
{ {
subscribersCopy = subscribers?.Where(s => s.Subscriber != null).ToHashSet() ?? []; subscribersCopy = subscribers?.Where(s => s.Subscriber != null).ToList() ?? [];
} }
foreach (SubscriberAction subscriber in subscribersCopy) #pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
GetType()
.GetMethod(nameof(ExecuteReflected), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?
.MakeGenericMethod(message.GetType())?
.Invoke(this, [subscribersCopy, message]);
#pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
}
private void ExecuteReflected<T>(List<SubscriberAction> subscribers, T message) where T : MessageBase
{
var msgTypeName = message.GetType().Name;
foreach (SubscriberAction subscriber in subscribers)
{ {
try try
{ {
#pragma warning disable S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields var isSameThread = message.KeepThreadContext ? "$" : string.Empty;
typeof(MareMediator) _performanceCollector.LogPerformance(this, $"{isSameThread}Execute>{msgTypeName}+{subscriber.Subscriber.GetType().Name}>{subscriber.Subscriber}",
.GetMethod(nameof(ExecuteSubscriber), System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)? () => ((Action<T>)subscriber.Action).Invoke(message));
.MakeGenericMethod(message.GetType())
.Invoke(this, new object[] { subscriber, message });
#pragma warning restore S3011 // Reflection should not be used to increase accessibility of classes, methods, or fields
} }
catch (Exception ex) catch (Exception ex)
{ {
if (_lastErrorTime.TryGetValue(subscriber, out var lastErrorTime) && lastErrorTime.Add(TimeSpan.FromSeconds(10)) > DateTime.UtcNow) if (_lastErrorTime.TryGetValue(subscriber, out var lastErrorTime) && lastErrorTime.Add(TimeSpan.FromSeconds(10)) > DateTime.UtcNow)
continue; continue;
_logger.LogError(ex.InnerException ?? ex, "Error executing {type} for subscriber {subscriber}", message.GetType().Name, subscriber.Subscriber.GetType().Name); _logger.LogError(ex.InnerException ?? ex, "Error executing {type} for subscriber {subscriber}",
message.GetType().Name, subscriber.Subscriber.GetType().Name);
_lastErrorTime[subscriber] = DateTime.UtcNow; _lastErrorTime[subscriber] = DateTime.UtcNow;
} }
} }
} }
private void ExecuteSubscriber<T>(SubscriberAction subscriber, T message) where T : MessageBase
{
var isSameThread = message.KeepThreadContext ? "$" : string.Empty;
_performanceCollector.LogPerformance(this, $"{isSameThread}Execute>{message.GetType().Name}+{subscriber.Subscriber.GetType().Name}>{subscriber.Subscriber}", () => ((Action<T>)subscriber.Action).Invoke(message));
}
private sealed class SubscriberAction private sealed class SubscriberAction
{ {
public SubscriberAction(IMediatorSubscriber subscriber, object action) public SubscriberAction(IMediatorSubscriber subscriber, object action)

View File

@@ -30,10 +30,13 @@ public static class Crypto
return GetOrComputeHashSHA256(stringToHash); return GetOrComputeHashSHA256(stringToHash);
} }
public static string GetHash256(this PlayerCharacter character) private static string GetOrComputeHashSHA256(string stringToCompute)
{ {
var charName = character.Name + character.HomeWorld.Id.ToString(); if (_hashListSHA256.TryGetValue(stringToCompute, out var hash))
return GetOrComputeHashSHA256(charName); return hash;
return _hashListSHA256[stringToCompute] =
BitConverter.ToString(_sha256CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
} }
private static string GetOrComputeHashSHA1(string stringToCompute) private static string GetOrComputeHashSHA1(string stringToCompute)
@@ -41,16 +44,11 @@ public static class Crypto
if (_hashListSHA1.TryGetValue(stringToCompute, out var hash)) if (_hashListSHA1.TryGetValue(stringToCompute, out var hash))
return hash; return hash;
return _hashListSHA1[stringToCompute] = BitConverter.ToString(_sha1CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal); return _hashListSHA1[stringToCompute] =
BitConverter.ToString(_sha1CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
} }
private static string GetOrComputeHashSHA256(string stringToCompute)
{
if (_hashListSHA256.TryGetValue(stringToCompute, out var hash))
return hash;
return _hashListSHA256[stringToCompute] = BitConverter.ToString(_sha256CryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(stringToCompute))).Replace("-", "", StringComparison.Ordinal);
}
#pragma warning restore SYSLIB0021 // Type or member is obsolete #pragma warning restore SYSLIB0021 // Type or member is obsolete
} }