Background: I’ve been working on a 3D tile based level system based on a modified marching cubes/tetrahedra approach. While populating the lookup table for tile selection and orientation I have been experiencing progressively longer build times that appear to be out of proportion with the amount of code I’m adding. By around the 200th entry build times have reached ~6 minutes. These times are the same both via build (not rebuild, not clean then build, just straight build) in VS 2013 Express (12.0.30110.00 Update 1) and via the Compile button in the Editor.
I searched the answers site and the forums (Extremely slow compiling - C++ - Unreal Engine Forums How to improve compile times for a C++ project? - Programming & Scripting - Unreal Engine Forums) and the answers found made no difference.
So I did some testing and found that the main culprit appears to be, that the compile time increases greatly (relatively) for every TSharedPtr that is created (might be references to TSharedPtr that are increasing it rather than creation specifically, haven’t tested that).
Included below is the data I’ve collected based on creating and placing shared pointers in a fixed length array. I’ve been comparing compile times using TSharedPtr against compile times using std::shared_ptr. All shared pointers are created and placed into the arrays individually, not within a loop (see code at the end of post).
I’ve separated the std::shared_ptr onto its own graph so that the effect on compile time can be better see. As you can see the number of entries in the array using std::shared_ptr has an approximately linear effect on compile time. The compile time when using TSharedPtr is increasing on a curve. With only 50 entries in the array the TSharedPtr version takes 3 times as long to compile, but if there are 400 entries being placed into the array it’s taking nearly 100 times longer to compile.
Here’s a set of classes that should reproduce the problem (copied from my project and rearranged for brevity so won’t compile without some modifications).
Notes: I tested with the TSharedPtr array in the UClass and in the normal c++ class, there is no difference. I couldn’t include memory for std::shared_ptr in the UClass without errors so I tested in the normal class. I tested an array of std::shared_ptr<FRotator> and the compile time is fine (so not a general issue with UE4 classes).
#pragma once
class Simplest
{
public:
Simplest() {};
};
----------------------------------------------------------------------
#pragma once
#include "Simplest.h"
class TestTSharedPtr
{
public:
TestTSharedPtr() {
lookupTable[0] = TSharedPtr<Simplest>(new Simplest());
lookupTable[1] = TSharedPtr<Simplest>(new Simplest());
lookupTable[2] = TSharedPtr<Simplest>(new Simplest());
lookupTable[3] = TSharedPtr<Simplest>(new Simplest());
...
lookupTable[198] = TSharedPtr<Simplest>(new Simplest());
lookupTable[199] = TSharedPtr<Simplest>(new Simplest());
};
TSharedPtr<Simplest> lookupTable[200];
};
----------------------------------------------------------------------
#pragma once
#include "memory"
#include "Simplest.h"
class TestStdSharedPtr
{
public:
TestStdSharedPtr() {
lookupTable[0] = std::shared_ptr<Simplest>(new Simplest());
lookupTable[1] = std::shared_ptr<Simplest>(new Simplest());
lookupTable[2] = std::shared_ptr<Simplest>(new Simplest());
lookupTable[3] = std::shared_ptr<Simplest>(new Simplest());
...
lookupTable[198] = std::shared_ptr<Simplest>(new Simplest());
lookupTable[199] = std::shared_ptr<Simplest>(new Simplest());
};
std::shared_ptr<Simplest> lookupTable[200];
};
----------------------------------------------------------------------
#pragma once
#include "TestStdSharedPtr.h" // or TestTSharedPtr.h
#include "GameFramework/Actor.h"
#include "GeneratedMap.generated.h"
/**
*
*/
UCLASS()
class AGeneratedMap : public AActor
{
GENERATED_UCLASS_BODY()
TestStdSharedPtr* testCase;
//TestTSharedPtr* testCase;
};
----------------------------------------------------------------------
#include "Blackbeard.h"
#include "GeneratedMap.h"
AGeneratedMap::AGeneratedMap(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
testCase = new TestStdSharedPtr(); // TestTSharedPtr();
};