From 3b999d25b4a68a609e2b4c92c18414c90eb36543 Mon Sep 17 00:00:00 2001 From: Rem Date: Sat, 15 Oct 2022 12:09:53 -0400 Subject: [PATCH] Optimized findPeriod to use a binary search into the 36 element period table O(log N) instead of O(N) lookups --- src/ace/managers/ptplayer.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/ace/managers/ptplayer.c b/src/ace/managers/ptplayer.c index c4eaba14..20936f62 100644 --- a/src/ace/managers/ptplayer.c +++ b/src/ace/managers/ptplayer.c @@ -1059,13 +1059,20 @@ static void printVoices(const tModVoice *pVoices) { } static inline UBYTE findPeriod(const UWORD *pPeriods, UWORD uwNote) { - // Find nearest period for a note value - for(UBYTE ubPeriodPos = 0; ubPeriodPos < MOD_PERIOD_TABLE_LENGTH; ++ubPeriodPos) { - if (uwNote >= pPeriods[ubPeriodPos]) { - return ubPeriodPos; + // Find nearest period (equal or lower) for a note value using a binary search lookup + UBYTE ubPeriodPos = 0; + UBYTE maxBound = MOD_PERIOD_TABLE_LENGTH; + while (ubPeriodPos != maxBound) { + UBYTE currentIndex = (ubPeriodPos + maxBound) >> 1; + // if this period is greater, skip 'bottom half' of the array and continue searching + if (pPeriods[currentIndex] > uwNote) { + ubPeriodPos = currentIndex + 1; + } + else { // else, the period we seek is between ubPeriodPos and currentIndex + maxBound = currentIndex; } } - return 0; + return ubPeriodPos; } static void ptSongStep(void) {