perf: a file view re-reads the file only when a structural change really dropped it
Three tightenings, all measured with the reloads now reported on stderr.
`set_math_channels()` treats an identical list as no change at all. It rebuilt
unconditionally, and a rebuild replaces the buffer and drops its history -- which a file
view then has to re-read from disk. The comparison is the graphs', and it leaves the nodes'
`x`/`y` out deliberately: those are the canvas's own, no op reads them, and a graph that
merely *moved* should not cost the buffer.
`reload_file_view()` fires only when the store is actually empty. A change that really
happened leaves it so in a file view (the rebuild replaces it, and there is no producer to
refill it); one that found nothing to do leaves it full, and reading a 200 MB file again for
that is the waste. `ScopeModel::stored_slots()` is the one-line accessor it needed.
Every reload now says so, because a second read of a file is worth accounting for:
[udpscope] reloaded <path> after a structural change: 402 samples back
Measured, `--open` a file:
session with no graphs 0 reloads
the math probe (3 real changes) 3 reloads, and all the readings stay equal
(`math x2 402 samples vs 402 time slots`)
I had offered this as "one extra read at `--open` startup", and that was wrong: with no
session there is no `apply_math_channels()` call at all, so there was never an extra read
to remove. What the tightenings buy is that a no-op application is now free, and that a
reload cannot happen unless the buffer was really lost. Each *genuine* change still costs
one re-read -- a rebuild drops the history by design, and preserving it across a rebuild is
a model change rather than this one.
This commit is contained in:
1 parent
b090cc2a21
commit
47d49e75ff
5 files changed
+45
-1
No files matched your search
@@ -58,6 +58,17 @@ struct MathNode {
|
||||
double hi = 1.0;
|
||||
double x = 0.0; ///< the editor's box position, logical pixels.
|
||||
double y = 0.0;
|
||||
|
||||
/// Whether two nodes are the same node for the *engine's* purposes.
|
||||
///
|
||||
/// `x`/`y` are the canvas's own and no op reads them, so a graph that only moved is not a change:
|
||||
/// rebuilding for it replaces the buffer and drops its history -- and in a file view that means
|
||||
/// re-reading the file -- to store two numbers nothing but the editor draws with.
|
||||
bool operator==(const MathNode& other) const {
|
||||
return op == other.op && source == other.source && in_a == other.in_a && in_b == other.in_b &&
|
||||
gain == other.gain && offset == other.offset && fc == other.fc && q == other.q &&
|
||||
lo == other.lo && hi == other.hi;
|
||||
}
|
||||
};
|
||||
|
||||
/// A derived channel: a graph of nodes and which node is the answer.
|
||||
@@ -67,6 +78,11 @@ struct MathChannel {
|
||||
bool enabled = false;
|
||||
std::vector<MathNode> nodes;
|
||||
int output = -1; ///< the node whose value is the channel's.
|
||||
|
||||
bool operator==(const MathChannel& other) const {
|
||||
return name == other.name && unit == other.unit && enabled == other.enabled &&
|
||||
output == other.output && nodes == other.nodes;
|
||||
}
|
||||
};
|
||||
|
||||
/// The per-channel runtime: the filter memory and the per-node scratch. Kept apart from the
|
||||
|
||||
Reference in new issue
Block a user