Note / UE · 2023年7月26日 0

[虚幻引擎] UE里面监控每帧循环里面 C++ 函数的性能, 函数耗时,函数效率,函数执行时间

在使用C++开发UE引擎,有时候需要监控函数的执行的执行效率,这个时候有两种方式可以使用。

1. 执行代码耗时时间

        double ThisTime = 0;
        {
           SCOPE_SECONDS_COUNTER(ThisTime);
            // ...
            // 一串代码
            // ...
        }
        UE_LOG(LogTemp, Log, TEXT("Stats::Broadcast %.2f"), ThisTime);

这样就可以输出这一段代码消耗时间,此方法会捕获时间(以秒为单位传递),并将增量时间添加到传入的变量。

2. 函数每帧监控

在一些函数是每帧都要执行的时候,那就可以用UE的统计系统来显示,这样更方便。

先在CPP定义一个自定义监听组

DECLARE_STATS_GROUP(TEXT("DTActor"), STATGROUP_DTActor, STATCAT_Test);

这样启动程序的时候, 就可以看到自己定义的组

[虚幻引擎] UE里面监控每帧循环里面 C++ 函数的性能,  函数耗时,函数效率,函数执行时间

然后需要定义函数监听模块

DECLARE_CYCLE_STAT(TEXT("DTActor Tick"), STAT_Tick, STATGROUP_DTActor);
DECLARE_CYCLE_STAT(TEXT("DTActor Call"), STAT_Call, STATGROUP_DTActor);

并在相应的函数中启动相应模块

void ADTActor::Tick(float DeltaTime)
{
	SCOPE_CYCLE_COUNTER(STAT_Tick);
	Super::Tick(DeltaTime);
}
void ADTActor::Call()
{
	SCOPE_CYCLE_COUNTER(STAT_Call);
}

这样在运行关卡的时候就会显示函数的具体执行时间

[虚幻引擎] UE里面监控每帧循环里面 C++ 函数的性能,  函数耗时,函数效率,函数执行时间

以下是这个Actor的完整代码,可以自己测试一下。

DTActor.h

// Copyright 2023 Dexter.Wan. All Rights Reserved. 
// EMail: 45141961@qq.com
// Website: https://dt.cq.cn/

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "DTActor.generated.h"

UCLASS()
class DTMOVIE_API ADTActor : public AActor
{
	GENERATED_BODY()

public:
	ADTActor();

protected:
	virtual void BeginPlay() override;

public:
	virtual void Tick(float DeltaTime) override;

	void Call();
};

DTActor.cpp

// Copyright 2023 Dexter.Wan. All Rights Reserved. 
// EMail: 45141961@qq.com
// Website: https://dt.cq.cn/

#include "DTActor.h"

DECLARE_STATS_GROUP(TEXT("DTActor"), STATGROUP_DTActor, STATCAT_Test);
DECLARE_CYCLE_STAT(TEXT("DTActor Tick"), STAT_Tick, STATGROUP_DTActor); 
DECLARE_CYCLE_STAT(TEXT("DTActor Call"), STAT_Call, STATGROUP_DTActor);

ADTActor::ADTActor()
{
	PrimaryActorTick.bCanEverTick = true;
}

void ADTActor::BeginPlay()
{
	Super::BeginPlay();
}

void ADTActor::Tick(float DeltaTime)
{
	SCOPE_CYCLE_COUNTER(STAT_Tick);
	Super::Tick(DeltaTime);

	FString S;
	for ( int n = 0; n < 50000; ++n )
	{
		S += TEXT("1");
	}

	Call();
	Call();
}

void ADTActor::Call()
{
	SCOPE_CYCLE_COUNTER(STAT_Call);

	FString S;
	for ( int n = 0; n < 50000; ++n )
	{
		S += TEXT("1");
	}
}