Simplify and speed up loading (very very slightly). It would be fastest to add all BPM/stop segments to the array and then sort it once (n log n). It was sorting after every insertion (n^2 log n). This now does simple insertion sort so it's n^2 in the worst case but since upper_bound does a binary search, if the BPM segments are in order this will take n log n in the best case.

That said, you'll notice no difference unless you had thousands of BPM changes in a file.
This commit is contained in:
Steve Checkoway
2006-07-20 01:56:17 +00:00
parent 4f4e034af1
commit 29e6e796ba
2 changed files with 15 additions and 47 deletions
+7 -41
View File
@@ -4,66 +4,35 @@
#include "RageUtil.h" #include "RageUtil.h"
#include "RageLog.h" #include "RageLog.h"
#include "NoteTypes.h" #include "NoteTypes.h"
#include "Foreach.h"
#include <float.h> #include <float.h>
void BPMSegment::SetBPM( float f )
{
m_fBPS = f / 60.0f;
}
float BPMSegment::GetBPM() const
{
return m_fBPS * 60.0f;
}
TimingData::TimingData() TimingData::TimingData()
{ {
m_fBeat0OffsetInSeconds = 0; m_fBeat0OffsetInSeconds = 0;
} }
static int CompareBPMSegments(const BPMSegment &seg1, const BPMSegment &seg2)
{
return seg1.m_iStartIndex < seg2.m_iStartIndex;
}
void SortBPMSegmentsArray( vector<BPMSegment> &arrayBPMSegments )
{
sort( arrayBPMSegments.begin(), arrayBPMSegments.end(), CompareBPMSegments );
}
static int CompareStopSegments(const StopSegment &seg1, const StopSegment &seg2)
{
return seg1.m_iStartRow < seg2.m_iStartRow;
}
void SortStopSegmentsArray( vector<StopSegment> &arrayStopSegments )
{
sort( arrayStopSegments.begin(), arrayStopSegments.end(), CompareStopSegments );
}
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
{ {
fMinBPMOut = FLT_MAX; fMinBPMOut = FLT_MAX;
fMaxBPMOut = 0; fMaxBPMOut = 0;
for( unsigned i=0; i<m_BPMSegments.size(); i++ ) FOREACH_CONST( BPMSegment, m_BPMSegments, seg )
{ {
const BPMSegment &seg = m_BPMSegments[i]; const float fBPM = seg->GetBPM();
fMaxBPMOut = max( seg.m_fBPS * 60.0f, fMaxBPMOut ); fMaxBPMOut = max( fBPM, fMaxBPMOut );
fMinBPMOut = min( seg.m_fBPS * 60.0f, fMinBPMOut ); fMinBPMOut = min( fBPM, fMinBPMOut );
} }
} }
void TimingData::AddBPMSegment( const BPMSegment &seg ) void TimingData::AddBPMSegment( const BPMSegment &seg )
{ {
m_BPMSegments.push_back( seg ); m_BPMSegments.insert( upper_bound(m_BPMSegments.begin(), m_BPMSegments.end(), seg), seg );
SortBPMSegmentsArray( m_BPMSegments );
} }
void TimingData::AddStopSegment( const StopSegment &seg ) void TimingData::AddStopSegment( const StopSegment &seg )
{ {
m_StopSegments.push_back( seg ); m_StopSegments.insert( upper_bound(m_StopSegments.begin(), m_StopSegments.end(), seg), seg );
SortStopSegmentsArray( m_StopSegments );
} }
/* Change an existing BPM segment, merge identical segments together or insert a new one. */ /* Change an existing BPM segment, merge identical segments together or insert a new one. */
@@ -187,10 +156,7 @@ BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat )
{ {
static BPMSegment empty; static BPMSegment empty;
if( m_BPMSegments.empty() ) if( m_BPMSegments.empty() )
{
empty = BPMSegment();
return empty; return empty;
}
int i = GetBPMSegmentIndexAtBeat( fBeat ); int i = GetBPMSegmentIndexAtBeat( fBeat );
return m_BPMSegments[i]; return m_BPMSegments[i];
+8 -6
View File
@@ -9,13 +9,13 @@
struct BPMSegment struct BPMSegment
{ {
BPMSegment() { m_iStartIndex = -1; m_fBPS = -1; } BPMSegment() : m_iStartIndex(-1), m_fBPS(-1.0f) { }
BPMSegment( int s, float b ) { m_iStartIndex = s; m_fBPS = b/60.0f; } BPMSegment( int s, float b ) { m_iStartIndex = max( 0, s ); SetBPM( b ); }
int m_iStartIndex; int m_iStartIndex;
float m_fBPS; float m_fBPS;
void SetBPM( float f ); void SetBPM( float f ) { m_fBPS = f / 60.0f; }
float GetBPM() const; float GetBPM() const { return m_fBPS * 60.0f; }
bool operator==( const BPMSegment &other ) const bool operator==( const BPMSegment &other ) const
{ {
@@ -24,12 +24,13 @@ struct BPMSegment
return true; return true;
} }
bool operator!=( const BPMSegment &other ) const { return !operator==(other); } bool operator!=( const BPMSegment &other ) const { return !operator==(other); }
bool operator<( const BPMSegment &other ) const { return m_iStartIndex < other.m_iStartIndex; }
}; };
struct StopSegment struct StopSegment
{ {
StopSegment() { m_fStopSeconds = -1; m_iStartRow = -1; } StopSegment() : m_iStartRow(-1), m_fStopSeconds(-1.0f) { }
StopSegment( int s, float f ) { m_iStartRow = s; m_fStopSeconds = f; } StopSegment( int s, float f ) { m_iStartRow = max( 0, s ); m_fStopSeconds = max( 0.0f, f ); }
int m_iStartRow; int m_iStartRow;
float m_fStopSeconds; float m_fStopSeconds;
@@ -40,6 +41,7 @@ struct StopSegment
return true; return true;
} }
bool operator!=( const StopSegment &other ) const { return !operator==(other); } bool operator!=( const StopSegment &other ) const { return !operator==(other); }
bool operator<( const StopSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
}; };
class TimingData class TimingData