Le 20/07/2024 à 21:23, Richard Kimberly Heck a écrit :
On 7/20/24 3:22 PM, Jean-Marc Lasgouttes wrote:
PS: the profiler tells me that more than 10% of this time is lost
updating macros over and over. I'll take a look at that.
That is at the root of a lot of the performance issues we have.
This is what I had in mind. It seems to work well. Does it look good to you?
Next step would be to skip updateMacros() when there is no macro. The
question is probably how we detect that a macro is inserted. We could
count macros in updateBuffer() (which is quick).
What I do not understand is how updateMacros handles children and
master. It looks like master is not taken in account, but this is really
not clear to me.
JMarc
From 3fc0fb8d73d5d251cf2d93097e34fdc6dc93a0b7 Mon Sep 17 00:00:00 2001
From: Jean-Marc Lasgouttes <lasgout...@lyx.org>
Date: Sat, 20 Jul 2024 22:31:34 +0200
Subject: [PATCH] Do not run updateMacros if the buffer has not changed
Each buffer now has an id which is increased when it is marked dirty
(or when one of its relatives is marked dirty).
This can be a big win since updateMacros is very expensive.
---
src/Buffer.cpp | 27 +++++++++++++++++++++++++++
src/Buffer.h | 6 ++++++
src/Undo.cpp | 6 ++++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/Buffer.cpp b/src/Buffer.cpp
index e95d0edcc8..fdba723227 100644
--- a/src/Buffer.cpp
+++ b/src/Buffer.cpp
@@ -253,6 +253,11 @@ public:
///
Undo undo_;
+ /// This is increased every time the buffer or one of its relatives is marked dirty
+ int id_ = 0;
+ /// The buffer id at last updateMacros invokation
+ int update_macros_id_ = -1;
+
/// A cache for the bibfiles (including bibfiles of loaded child
/// documents), needed for appropriate update of natbib labels.
mutable docstring_list bibfiles_cache_;
@@ -808,6 +813,20 @@ Undo const & Buffer::undo() const
}
+int Buffer::id() const
+{
+ return d->id_;
+}
+
+
+void Buffer::updateId()
+{
+ ++d->id_;
+ for(Buffer * b : allRelatives())
+ ++(b->d->id_);
+}
+
+
void Buffer::setChild(DocIterator const & dit, Buffer * child)
{
d->children_positions[child] = dit;
@@ -3323,6 +3342,9 @@ void Buffer::markDirty()
for (auto & depit : d->dep_clean)
depit.second = false;
+
+ // Update the buffer and its relatives' ids.
+ updateId();
}
@@ -3917,6 +3939,11 @@ void Buffer::updateMacros() const
if (d->macro_lock)
return;
+ // early exit if the buffer has not changed since last time
+ if (d->update_macros_id_ == d->id_)
+ return;
+ d->update_macros_id_ = d->id_;
+
LYXERR(Debug::MACROS, "updateMacro of " << d->filename.onlyFileName());
// start with empty table
diff --git a/src/Buffer.h b/src/Buffer.h
index d9e7e325d4..1498b7f89c 100644
--- a/src/Buffer.h
+++ b/src/Buffer.h
@@ -660,6 +660,12 @@ public:
///
Undo const & undo() const;
+ /// poor man versioning of the buffer (and its relatives).
+ int id() const;
+ /// change the id of this buffer and its relatives (indicating
+ /// something has changed). This is currently used by updateMacros().
+ void updateId();
+
/// This function is called when the buffer is changed.
void changed(bool update_metrics) const;
///
diff --git a/src/Undo.cpp b/src/Undo.cpp
index 80dff34baa..5eb29bf7a0 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -529,9 +529,11 @@ void Undo::Private::doUndoRedoAction(CursorData & cur, UndoElementStack & stack,
if (!undo.cur_before.empty())
cur = undo.cur_before;
- if (undo.lyx_clean)
+ if (undo.lyx_clean) {
buffer_.markClean();
- else
+ // since we have changed the buffer, update its id.
+ buffer_.updateId();
+ } else
buffer_.markDirty();
// Now that we're done with undo, we pop it off the stack.
stack.pop();
--
2.43.0
--
lyx-devel mailing list
lyx-devel@lists.lyx.org
http://lists.lyx.org/mailman/listinfo/lyx-devel