From 7d50301b46d6d9638aab3579e3a330f2cb01b267 Mon Sep 17 00:00:00 2001 From: Zachary Burke Date: Tue, 2 Jan 2018 09:36:22 -0800 Subject: [PATCH] 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 --- es-app/src/FileData.cpp | 2 +- es-app/src/PlatformId.cpp | 48 ++++++++++++++++++++++++++++++++++----- es-app/src/PlatformId.h | 7 +++++- 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 9ba6c082d..31e636819 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -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; } diff --git a/es-app/src/PlatformId.cpp b/es-app/src/PlatformId.cpp index bf37bc52b..e437a367c 100644 --- a/es-app/src/PlatformId.cpp +++ b/es-app/src/PlatformId.cpp @@ -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; } + } diff --git a/es-app/src/PlatformId.h b/es-app/src/PlatformId.h index 8b08cde0f..be553e8fc 100644 --- a/es-app/src/PlatformId.h +++ b/es-app/src/PlatformId.h @@ -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