我们经常会遇到一些大耗时点却看不到细节的情况,比如SpawnActor的时候我们更希望知道我们Spawn了什么Actor导致了瓶颈,这个时候自定义字符串stats就可以发挥它的作用。
实际在使用中和普通stats类似
不过需要注意的是,statsID的数量是有限的,如果我们用物体名去定义StatsID,那么会有大量的StatsID,导致数字溢出而导致崩溃,并且CreateStatsID的耗时会大大增加,得不偿失,所以一般我们建议使用ClassName或者其他并不会导致大量不重复字符串的方式来申请statsID。
实现方式实际非常简单,只是将CreateStatsID的步骤自行包装并且缓存起来而已。
https://gist.github.com/vgvgvvv/dbdbfb3574768cc80969c1cb827868c0
//DynamicStats.h
# pragma once
# include "Stats2.h"
# include "Map.h"
# if STATS
DECLARE_STATS_GROUP(TEXT("Dynamic"), STATGROUP_Dynamic, STATCAT_Advanced);
class FDynamicScopeCycleCounter : public FCycleCounter
{
public:
FDynamicScopeCycleCounter(FString FunctionName)
{
TStatId statID = GetStatIdForFunction("[Dynamic]" + FunctionName);
if (FThreadStats::IsCollectingData(statID))
{
Start(statID);
}
}
~FDynamicScopeCycleCounter()
{
Stop();
}
private:
TStatId GetStatIdForFunction(FString FunctionName)
{
static TMap<FString, TStatId> FunctionStatIdMap;
if (FunctionStatIdMap.Contains(FunctionName))
{
return FunctionStatIdMap[FunctionName];
}
else
{
TStatId statID = FDynamicStats::CreateStatId<FStatGroup_STATGROUP_Dynamic>(FunctionName);
FunctionStatIdMap.Add(FunctionName, statID);
return statID;
}
}
};
# if UE_BUILD_TEST || UE_EDITOR
# define DYNAMIC_SCOPE_CYCLE_COUNTER(name, showname) \
FDynamicScopeCycleCounter name##Counter(showname);
# else
# define DYNAMIC_SCOPE_CYCLE_COUNTER(name, showname)
# endif
# else
# define DYNAMIC_SCOPE_CYCLE_COUNTER(name, showname)
# endif