There are actually two different implementations of UClass::IsChildOf (which is used by IsA).
See Engine Source on GitHub
https://github.com/EpicGames/UnrealEngine/blob/d94b38ae3446da52224bedd2568c078f828b4039/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h#L480
https://github.com/EpicGames/UnrealEngine/blob/99b6e203a15d04fc7bbbf554c421a985c1ccb8f1/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L2197
The implementation is chosen like
#if UE_EDITOR || HACK_HEADER_GENERATOR
// On editor, we use the outerwalk implementation because BP reinstancing and hot reload
// mess up the struct array
#define USTRUCT_FAST_ISCHILDOF_IMPL USTRUCT_ISCHILDOF_OUTERWALK
#else
#define USTRUCT_FAST_ISCHILDOF_IMPL USTRUCT_ISCHILDOF_STRUCTARRAY
#endif
The USTRUCT_ISCHILDOF_STRUCTARRAY implementation caches an array of superstructs and the number of bases in the constructor of UStruct. Then the actual IsChildOfUsingStructArray implementation needs to compare only the number of bases as well as whether `` has the given Parent at the corresponding index in its array of superstructs.
See Engine Source on GitHub
https://github.com/EpicGames/UnrealEngine/blob/99b6e203a15d04fc7bbbf554c421a985c1ccb8f1/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L4347
https://github.com/EpicGames/UnrealEngine/blob/d94b38ae3446da52224bedd2568c078f828b4039/Engine/Source/Runtime/CoreUObject/Public/UObject/Class.h#L271