From 1ae250301466c950248de5b5681954013bad21f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Mon, 16 Jun 2025 21:52:10 +0200 Subject: [PATCH] custom_model: open-code QtCore.QAbstractItemModel.hasIndex() The implementation is just bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const { if (row < 0 || column < 0) return false; return row < rowCount(parent) && column < columnCount(parent); } and yet it features as the most prominent part of the profile, encompassing up to 25% of refresh() Open-coding it makes refresh() 40% faster. Measurements from between after wallet.get_full_history() and return from refresh() Before: 1.8637257907539606 1.8563996930606663 1.7696567592211068 1.8933695629239082 After: 1.3133591176010668 1.3686819169670343 1.2470976510085166 1.2455544411204755 --- electrum/gui/qt/custom_model.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/electrum/gui/qt/custom_model.py b/electrum/gui/qt/custom_model.py index 099e041b3..e9f9b05dc 100644 --- a/electrum/gui/qt/custom_model.py +++ b/electrum/gui/qt/custom_model.py @@ -62,12 +62,18 @@ class CustomModel(QtCore.QAbstractItemModel): parent.addChild(self, node) def index(self, row, column, _parent=None): + # Performance-critical function + if not _parent or not _parent.isValid(): parent = self._root else: parent = _parent.internalPointer() - if not QtCore.QAbstractItemModel.hasIndex(self, row, column, _parent): + # Open-coded + # if not QtCore.QAbstractItemModel.hasIndex(self, row, column, _parent): + # the implementation is equivalent but it's in C++, + # so VM entries take up inordinate amounts of time (up to 25% of refresh()): + if row < 0 or column < 0 or row >= self.rowCount(_parent) or column >= self._columncount: return QtCore.QModelIndex() child = parent.child(row)