Majorly improved performance when fetching Mame names.

After profiling UI filtering and startup I determined that
getCleanMameName was responsible for the incredibly long load times when
loading/filtering Mame ROMS. This function was using a linear search
over a pre-sorted array to find a corresponding Mame ROM Name from the
ROM name. It now uses a binary search which improves UI load/filter
responsiveness by a couple orders of magnitude.

Single core performance on my i7 for 10,000 iterations was 2.01 secs vs
7.77e-4 secs
This commit is contained in:
Zachary Burke 2018-01-02 09:36:22 -08:00 committed by
parent f93390b87f
commit 7d50301b46
3 changed files with 49 additions and 8 deletions

View file

@ -40,7 +40,7 @@ std::string FileData::getDisplayName() const
{
std::string stem = mPath.stem().generic_string();
if(mSystem && mSystem->hasPlatformId(PlatformIds::ARCADE) || mSystem->hasPlatformId(PlatformIds::NEOGEO))
stem = PlatformIds::getCleanMameName(stem.c_str());
stem = PlatformIds::mameTitleSearch(stem.c_str());
return stem;
}

View file

@ -95,16 +95,52 @@ namespace PlatformIds
return PlatformNames[id];
}
const char* getCleanMameName(const char* from)
int getMameTitleCount()
{
const char** mameNames = mameNameToRealName;
while(*mameNames != NULL && strcmp(from, *mameNames) != 0)
int count = 0;
while (*mameNames != NULL)
{
mameNames += 2;
count++;
}
return count;
}
if(*mameNames)
return *(mameNames + 1);
const char* mameTitleSearch(const char* from)
{
// The start and end index range from [0, number of roms]
int iStart = 0;
static int mameCount = getMameTitleCount();
int iEnd = mameCount;
while (iStart < iEnd)
{
// The middle entry is halfway between the start and end index
const int iMiddle = (iStart + iEnd) / 2;
// mameNameToRealName contains 2 sequential entries for every entry, so the indexes look like this:
// 0: key, value,
// 2: key, value,
// 4: key, value
// This means that there are twice as many indexes as there are numbers of ROMs. So to get the
// iMiddle'th entry, we need to multiply by 2 because iMiddle goes from [0, number of roms].
const int iKey = iMiddle * 2;
const int comp = strcmp(mameNameToRealName[iKey], from);
if (comp < 0)
{
// Remember, iMiddle ranges from [0, number of roms] so we only increment by 1
iStart = iMiddle + 1;
}
else if (comp > 0)
{
iEnd = iMiddle;
}
// The Key was found, now return the Value
else return mameNameToRealName[iKey + 1];
}
return from;
}
}

View file

@ -78,7 +78,12 @@ namespace PlatformIds
PlatformId getPlatformId(const char* str);
const char* getPlatformName(PlatformId id);
const char* getCleanMameName(const char* from);
// Get the number of Mame titles in the mameNameToRealName array
// Should only run this once and store in a static or cached variable
int getMameTitleCount();
// Perform a binary search for a game title given a rom name
const char* mameTitleSearch(const char* from);
}
#endif // ES_APP_PLATFORM_ID_H