Afforess
The White Wizard
This change has a big performance impact, i ran 2 turns taking 90seconds and ~30second are used for CvBuildingInfo::isReplaceBuildingClass and CvPlayer::getBuildingClassCountWithUpgrades!
I wonder why nobody else noticed it because this is alot compared to e.g. the impact from trade routes.
I am very doubtful of your findings. I am not saying you are wrong, but if I were a betting man, I would be betting against you heavily.
Why am I so dubious? Let's see the code:
Code:
int CvPlayer::getBuildingClassCountWithUpgrades(BuildingClassTypes eBuildingClass) const
{
int iCount;
iCount = getBuildingClassCount(eBuildingClass);
BuildingTypes eBuilding = (BuildingTypes)GC.getCivilizationInfo(getCivilizationType()).getCivilizationBuildings(eBuildingClass);
if (eBuilding != NO_BUILDING && GC.getBuildingInfo(eBuilding).isReplaceBuildingClass(NO_BUILDINGCLASS))
{
for (int iI = 0; iI < GC.getNumBuildingClassInfos(); iI++)
{
if (GC.getBuildingInfo(eBuilding).isReplaceBuildingClass(iI))
{
iCount += getBuildingClassCount((BuildingClassTypes)iI);
}
}
}
return iCount;
}
If the building has no replacements (like 98% of buildings are never replaced) there is zero extra cost in terms of performance. The "GC.getBuildingInfo(eBuilding).isReplaceBuildingClass(NO_BUILDINGCLASS)" check will return false if the building has no replacements.
If it does have replacements, it scans all building classes, then adds the additional counts. getBuildingClassCount is a simple arrray access. There should be nearly no performance hit for this sort of calculation.
There are three possible reasons for your strange results:
1.) You tested the change on C2C and not RAND and didn't know I fixed a bug related to GC.getBuildingInfo(eBuilding).isReplaceBuildingClass(NO_BUILDINGCLASS)) that was causing it to not work as expected.
2.) You tested the change on RAND and your profiling results are wrong (miscalibration, wrong profiling scope?)
3.) You tested the change on RAND and your profiling results are correct, and I am wrong.
I am betting on #1.

Spoiler :
The fix I mentioned in #1 was a bug that caused the replacement building array in CvInfos to be assigned to garbage values (when it should have been NULL) when there was no XML tag. The fix is here. It occurs because Koshling (I assume, or someone else in C2C) tried to optimize replacement buildings by not allocating an array when there were no replacements, but didn't actually assign a valid NULL to the pointer in that scenario. InitList(...) was only called when there *was* an XML tag, so the XML tag remained the default uninitialized pointer. For added fun, this would not show up in a debug DLL, as the debug flag causes uninitialized pointers to be set to NULL by default.