How you easily measure the time it takes a block of C++ code to run?

I know I can do the equivalent of

a = time; { some slow code } print time - a;

But I wanted to know whether Unreal has any nice convenience functions or macros. PLEASE, nothing heavy-handed that involves toggling things in the console, writing, reading, and locating trace files, or complicated GUIs that load said files and display 10,000 things I’m not interested in.

I just want to measure execution time for a block of C++ code. Thank you.

1 Like

You can create stats groups in your C++ files, and create add scoped blocks in your code to measure time just like you would see if you typed for example “stat gpu” in the console. In your .h or .cpp file first create a stats group using DECLARE_STATS_GROUP(TEXT("MyStatsGroup"), STATGROUP_MyStatsGroup, STATCAT_Advanced);

Then also create a stat using DECLARE_CYCLE_STAT(TEXT("MyExpensiveFunction"), STAT_MyExpensiveFunction, STATGROUP_MyStatsGroup);

Finally, surround the code that you want to measure in a scope, like so:
{ SCOPE_CYCLE_COUNTER(STAT_MyExpensiveFunction); ExpensiveFunction(); }

Then in the editor, you can press the “`” key to open the console and if you type stat mystatsgroup, you should see the familiar stats overlay

From my project:

5 Likes

Thank you for the clear explanation, and for confirming this is the way to go. However, I had tried this approach before, and couldn’t get it to work. And still can’t. I followed your instructions exactly. I get a table in the viewport showing the names of my stats. When I run the game, I get some numbers in the table for less than a second, then they vanish. The ‘call count’ never goes above zero.

So my next question is, does this method only work on functions that get called repeatedly in the game loop, in the same session? Because the functions I’m interested in only occur once, at initialization time. I was hoping this would keep an average across runs.

I should just write my own profiling functions and be done with it. I’ve been on this for days.

In that case you can always do something like:

FDateTime StartTime = FDateTime::UtcNow();
ExpensiveFunction();
float TimeElapsedInMs = (FDateTime::UtcNow() - StartTime).GetTotalMilliseconds();
UE_LOG(LogTemp, Display, TEXT(“%f”), TimeElapsedInMs)

You can also use GetTotalMicroseconds, or GetTotalSeconds, accordingly.

EDIT: Just saw that you mentioned this approach in your original post, but I will leave this here in case anyone else is interested

3 Likes

Yeah, I’ll make a lot more progress if I go the low-tech route. But it’s good to know how to use those macros - I didn’t really know how to view them with stat. When I get to it, I’ll try putting one in a function that gets called a lot, and see if it becomes useful. Thanks for your help.