I've just been playing about with cachegrind to see if I could tweak some performance
improvements out of general usability. One thing it pointed out was the amount of
time spent in certain core functions like Composition::ReferenceSegment::findTime
and others during a file load. Looks like to me this is because of the Event
construction
taking place in each one - not significant in itself but when it's called almost 14,000
times in a file load it soon takes its toll.
I've just created this scratchy DummyEvent that you can reset the times for and
substituted
it into Composition, Segment, SegmentNotationHelper to see if it helps. I think it
does but
the DummyEvent implementation is very minimal - it would also be good to throw away all
properties at reset().
Anyway, I've not committed it because it's half wrong and I'm pretty sure it breaks
something
else but have a think (Chris). Couldn't work out how to make a patch with a new file
in it
so DummyEvent.h goes into base/. The alternative of course to using static Events
like this
is to shuffle in some kind of block memory management code to improve efficiency.
BTW that pregnant pause when loading MIDI files is really very annoying now as well.
R
Index: base/Composition.C
===================================================================
RCS file: /cvsroot/rosegarden/base/Composition.C,v
retrieving revision 1.174
diff -b -u -p -r1.174 Composition.C
--- base/Composition.C 22 May 2003 10:41:28 -0000 1.174
+++ base/Composition.C 2 Jun 2003 08:02:04 -0000
@@ -23,6 +23,7 @@
#include "Segment.h"
#include "FastVector.h"
#include "Quantizer.h"
+#include "DummyEvent.h"
#include <iostream>
#include <iomanip>
@@ -52,6 +53,7 @@ const std::string Composition::TempoEven
const PropertyName Composition::TempoProperty = "BeatsPerHour";
const PropertyName Composition::TempoTimestampProperty = "TimestampSec";
+static DummyEvent dummyEvent(0, 0, MIN_SUBORDERING);
bool
Composition::ReferenceSegmentEventCmp::operator()(const Event &e1,
@@ -185,17 +187,17 @@ Composition::ReferenceSegment::erase(Eve
Composition::ReferenceSegment::iterator
Composition::ReferenceSegment::findTime(timeT t)
{
- Event dummy("dummy", t, 0, MIN_SUBORDERING);
- return find(&dummy);
+ dummyEvent.reset(t, 0, MIN_SUBORDERING);
+ return find(&dummyEvent);
}
Composition::ReferenceSegment::iterator
Composition::ReferenceSegment::findRealTime(RealTime t)
{
- Event dummy("dummy", 0, 0, MIN_SUBORDERING);
- dummy.set<Bool>(NoAbsoluteTimeProperty, true);
- setTempoTimestamp(&dummy, t);
- return find(&dummy);
+ dummyEvent.reset(0, 0, MIN_SUBORDERING);
+ dummyEvent.set<Bool>(NoAbsoluteTimeProperty, true);
+ setTempoTimestamp(&dummyEvent, t);
+ return find(&dummyEvent);
}
Composition::ReferenceSegment::iterator
@@ -495,12 +497,12 @@ Composition::getBarRange(int n) const
{
calculateBarPositions();
- Event dummy("dummy", 0);
- dummy.set<Int>(BarNumberProperty, n);
+ dummyEvent.reset(0, 0, MIN_SUBORDERING);
+ dummyEvent.set<Int>(BarNumberProperty, n);
ReferenceSegment::iterator j = std::lower_bound
(m_timeSigSegment.begin(), m_timeSigSegment.end(),
- &dummy, BarNumberComparator());
+ &dummyEvent, BarNumberComparator());
ReferenceSegment::iterator i = j;
if (i == m_timeSigSegment.end() || (*i)->get<Int>(BarNumberProperty) > n) {
Index: base/Segment.C
===================================================================
RCS file: /cvsroot/rosegarden/base/Segment.C,v
retrieving revision 1.175
diff -b -u -p -r1.175 Segment.C
--- base/Segment.C 28 May 2003 21:22:13 -0000 1.175
+++ base/Segment.C 2 Jun 2003 08:02:04 -0000
@@ -24,6 +24,7 @@
#include "BaseProperties.h"
#include "Composition.h"
#include "Quantizer.h"
+#include "DummyEvent.h"
#include <iostream>
#include <algorithm>
@@ -36,6 +37,7 @@ using std::cerr;
using std::endl;
using std::string;
+static DummyEvent dummyEvent(0, 0, MIN_SUBORDERING);
Segment::Segment(SegmentType segmentType, timeT startTime) :
@@ -423,8 +425,8 @@ Segment::findSingle(Event* e) const
Segment::iterator
Segment::findTime(timeT t) const
{
- Event dummy("dummy", t, 0, MIN_SUBORDERING);
- return lower_bound(&dummy);
+ dummyEvent.reset(t, 0, MIN_SUBORDERING);
+ return lower_bound(&dummyEvent);
}
@@ -705,7 +707,7 @@ Segment::normalizeRests(timeT startTime,
void Segment::getTimeSlice(timeT absoluteTime, iterator &start, iterator &end)
const
{
- Event dummy("dummy", absoluteTime, 0, MIN_SUBORDERING);
+ dummyEvent.reset(absoluteTime, 0, MIN_SUBORDERING);
// No, this won't work -- we need to include things that don't
// compare equal because they have different suborderings, as long
@@ -718,7 +720,7 @@ void Segment::getTimeSlice(timeT absolut
// Got to do this instead:
- start = end = lower_bound(&dummy);
+ start = end = lower_bound(&dummyEvent);
while (end != this->end() &&
(*end)->getAbsoluteTime() == (*start)->getAbsoluteTime())
Index: base/SegmentNotationHelper.C
===================================================================
RCS file: /cvsroot/rosegarden/base/SegmentNotationHelper.C,v
retrieving revision 1.114
diff -b -u -p -r1.114 SegmentNotationHelper.C
--- base/SegmentNotationHelper.C 28 May 2003 21:22:13 -0000 1.114
+++ base/SegmentNotationHelper.C 2 Jun 2003 08:02:09 -0000
@@ -24,6 +24,7 @@
#include "Quantizer.h"
#include "BaseProperties.h"
#include "Composition.h"
+#include "DummyEvent.h"
#include <iostream>
#include <algorithm>
@@ -39,6 +40,7 @@ using std::list;
using namespace BaseProperties;
+static DummyEvent dummyEvent(0, 0, MIN_SUBORDERING);
SegmentNotationHelper::~SegmentNotationHelper() { }
@@ -1538,12 +1540,12 @@ SegmentNotationHelper::guessClef(iterato
bool
SegmentNotationHelper::removeRests(timeT time, timeT &duration, bool testOnly)
{
- Event dummy("dummy", time, 0, MIN_SUBORDERING);
+ dummyEvent.reset(time, 0, MIN_SUBORDERING);
cerr << "SegmentNotationHelper::removeRests(" << time
<< ", " << duration << ")\n";
- iterator from = segment().lower_bound(&dummy);
+ iterator from = segment().lower_bound(&dummyEvent);
// ignore any number of zero-duration events at the start
while (from != segment().end() &&
// -*- c-basic-offset: 4 -*-
/*
Rosegarden-4
A sequencer and musical notation editor.
This program is Copyright 2000-2003
Guillaume Laurent <[EMAIL PROTECTED]>,
Chris Cannam <[EMAIL PROTECTED]>,
Richard Bown <[EMAIL PROTECTED]>
The moral right of the authors to claim authorship of this work
has been asserted.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
*/
#ifndef _DUMMYEVENT_H_
#define _DUMMYEVENT_H_
#include "Event.h"
/*
* A resettable DummyEvent that we can use for Segment/Composition
* calculations without having to throw away between uses.
*
*/
namespace Rosegarden
{
class DummyEvent : public Event
{
public:
DummyEvent(timeT absoluteTime,
timeT duration = 0,
short subOrdering = 0) :
Event("dummy", absoluteTime, duration, subOrdering) {;}
/*
DummyEvent(const Event &e) : Event(e) { ; }
DummyEvent(const Event &e, timeT absoluteTime) :
Event(e, absoluteTime) { ; }
DummyEvent(const Event &e, timeT absoluteTime, timeT duration) :
Event(e, absoluteTime, duration) { ; }
DummyEvent(const Event &e,
timeT absoluteTime, timeT duration, short subOrdering) :
Event(e, absoluteTime, duration, subOrdering) { ; }
*/
void reset(timeT absoluteTime,
timeT duration = 0,
short subOrdering = 0)
{
setAbsoluteTime(absoluteTime);
setDuration(duration);
setSubOrdering(subOrdering);
}
};
}
#endif // _DUMMYEVENT_H_