Optimized Blueprint Component Initialization

The Problem

Initializing Components that were added in Blueprint Editor is slower than those added in C++ via CreateDefaultSubobject. This affects the total time to spawn Actors both during the loadscreen, level streaming and through gameplay.

Solutions

Initializing more of your components in C++ (especially those that are spawned at runtime outside of the initial loading screen). Alternatively, using bOptimizeBPComponentData which can reduce this initialization overhead by caching properties per component of the Blueprint class its enabled for.

Checkbox: "Generate Optimized Blueprint Component Data"

Enabling bOptimizeBPComponentData (Found in Actor's properties) caches properties during cooking so that the per-component initialization can be optimized. This does have a measurable difference in performance, but you really need to know where to look.

“Whether to cook additional data to speed up spawn events at runtime for any Blueprint classes based on this Actor. This option may slightly increase memory usage in a cooked build.” - Engine Source Comment

Note: This optimization is only applied to Components added in Blueprint, instanced components via the C++ constructor are unaffected.

Profiling the Change

To verify the initialization logic is actually improved there is a CVAR available. Run the following command:

LogBlueprintComponentInstanceCalls 1

Important to note is that LogBlueprint must be set to Log or Verbose to actually show up in your log files. By default this may be set to NoLogging. Run the following command:

log LogBlueprint Verbose

In my test with a Torpedo Projectile Blueprint class with no native logic (derived from Actor) I could see meaningful differences in the logged time spent inside CreateComponentFromTemplate vs. CreateComponentFromTemplateData ("TemplateData" variant is the function that has the caching mechanism)

In the log files of your packaged game, look for "CreateComponentFromTemplate" in the log to see the stats from either function.

This setting can be enabled for All Blueprints in the Cooker settings (Project Settings > Cooker > Advanced > BlueprintComponentDataCookingMethod).

"Generate optimized component data to speed up Blueprint construction at runtime. This option can increase the overall Blueprint memory usage in a cooked build. Requires Event-Driven Loading (EDL), which is enabled by default."

Memory Footprint

As far as my understanding the memory footprint can be tracked inside InheritableComponentHandler by using obj list class=InheritableComponentHandler

You should be able to observe a slight increase in memory cost for any class with this feature enabled. In my testing with relatively small and simple setup about 1-2KB per class.

Takeaways

  • Initializing Components in C++ is faster than those added in Blueprint. This may affect your (base) class design.
  • bOptimizeBPComponentData provides an easy to improve initialization performance if many Actors use Blueprint added Components.
  • There is a slight increase in memory footprint per BP component in the Actor.
  • Best way to measure is the built-in logging.
  • Requires Cooked data to test.


Complete and Continue  
Discussion

0 comments