Inefficiency in FWorldPartitionLevelHelper::RemapLevelSoftObjectPaths during PIE startup

Hi! While investigating the slow PIE startup times, I’ve found that quite a bit of time is spent in `FWorldPartitionLevelHelper::RemapLevelSoftObjectPaths`. What it does is create a special FArchive and then serializes the world’s persistent level and all objects that have it as outer (~78k in total in my example, which takes about 2 seconds) through it. Pretty much all this time is wasted - in my example, the fixup function is called a grand total of 235 times, and only 4 of these calls actually end up modifying the property (and all 4 of them reference the same object). There has to be a better way of doing this operation…

I’ve tried replacing this serialization with a simple reflection-based visitor (see code below) - this reduces the time from 2 seconds to approximately 100ms in my example. Of course, there are semantic differences between these two ways (eg. there could be custom serialization code that visits non-reflected properties), but I’m not sure how important is it in practice.

auto Fixup = [InWorldPartition](UObject* Obj) { for (TPropertyValueIterator<FSoftObjectProperty> It(Obj->GetClass(), Obj); It; ++It) { auto& Value = It.Key()->GetPropertyValuePtr((void*)It.Value())->GetUniqueID(); if (!Value.IsNull()) { InWorldPartition->RemapSoftObjectPath(Value); } } }; Fixup(InLevel); ForEachObjectWithOuter(InLevel, Fixup);

Hello,

I apologize for the delay. I created a ticket to investigate improving this and shared the details you provided.

Thanks,

Ryan