요약

BP/C++에서 함수의 동작 시간을 측정하기 위한 코드 조각

코드에서는 매크로를 통한 Auto 버전을 통해 간편하게 사용

  #define TIME_MEASURE_START() UAPBlueprintFunctionLibrary::StartTimeMeasure_Auto(__FUNCTION__)
#define TIME_MEASURE_END()   UAPBlueprintFunctionLibrary::EndTimefMeasure_Auto(__FUNCTION__)
#define TIME_MEASURE_AVG()   UAPBlueprintFunctionLibrary::CalcAvgTime_Auto(__FUNCTION__)

public:
	UFUNCTION(BlueprintCallable, Category="Performance")
	static double GetTimeInMilliseconds();
	UFUNCTION(BlueprintCallable, Category = "Performance")
	static double BP_StartTimeMeasure();
	UFUNCTION(BlueprintCallable, Category = "Performance")
	static double BP_EndTimeMeasure(FString FunctionName, bool bPrint = true);
	UFUNCTION(BlueprintCallable, Category = "Performance")
	static double BP_CalcAvgTime(FString FunctionName, bool bPrint = true);

    static double StartTimeMeasure_Auto(const char* FuncName)
    {
        return BP_StartTimeMeasure(FString(FuncName));
    }

    static double EndTimefMeasure_Auto(const char* FuncName, bool bPrint = true)
    {
        return BP_EndTimeMeasure(FString(FuncName), bPrint);
    }

    static double CalcAvgTime_Auto(const char* FuncName, bool bPrint = true)
    {
        return BP_CalcAvgTime(FString(FuncName), bPrint);
    }

private:
	static TMap<FString, double> FunctionStartTimes;
	static TMap<FString, double> FunctionExecutionTotals;
	static TMap<FString, int32> FunctionExecutionCounts;
	static int ExecutionCnt;
  
  // 정의
TMap<FString, double> UAPBlueprintFunctionLibrary::FunctionStartTimes;
TMap<FString, double> UAPBlueprintFunctionLibrary::FunctionExecutionTotals;
TMap<FString, int32> UAPBlueprintFunctionLibrary::FunctionExecutionCounts;

// Start
double UAPBlueprintFunctionLibrary::BP_StartTimeMeasure(FString FunctionName)
{
	double Now = FPlatformTime::Seconds() * 1000.0;
	FunctionStartTimes.Add(FunctionName, Now);
	return Now;
}

// End
double UAPBlueprintFunctionLibrary::BP_EndTimeMeasure(FString FunctionName, bool bPrint)
{
	double Now = FPlatformTime::Seconds() * 1000.0;

	if (!FunctionStartTimes.Contains(FunctionName)) return -1.0;

	double Start = FunctionStartTimes[FunctionName];
	double Elapsed = Now - Start;

	FunctionExecutionTotals.FindOrAdd(FunctionName) += Elapsed;
	FunctionExecutionCounts.FindOrAdd(FunctionName) += 1;

	if (bPrint)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red,
			FString::Printf(TEXT("Function %s took %f ms"), *FunctionName, Elapsed));
	}

	return Elapsed;
}

// Average
double UAPBlueprintFunctionLibrary::BP_CalcAvgTime(FString FunctionName, bool bPrint)
{
	int32 Count = FunctionExecutionCounts.FindRef(FunctionName);
	double Total = FunctionExecutionTotals.FindRef(FunctionName);

	if (Count == 0) return -1.0;

	double Avg = Total / Count;

	FunctionExecutionCounts[FunctionName] = 0;
	FunctionExecutionTotals[FunctionName] = 0.0;

	if (bPrint)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red,
			FString::Printf(TEXT("Function %s took Avg %f ms"), *FunctionName, Avg));
	}

	return Avg;
}