Skip to content
GitLab
  • Menu
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • thg thg
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 829
    • Issues 829
    • List
    • Boards
    • Service Desk
    • Milestones
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • mercurial
  • TortoiseHg
  • thgthg
  • Issues
  • #5061
Closed
Open
Created Mar 26, 2018 by Bitbucket Importer@bitbucket_importerOwner

PyQt5 graph view "lazy loading" seems broken with graphopt

Created originally on Bitbucket by lothiraldan (Boris FELD)

I am debugging a performance issue on a pretty big repository (~525000 revisions). The repository is also quite branchy (+20000 heads). All the tests were made on a Mac Mini Sierra (10.12.6).

Opening the repository with thg 4.5 Qt4 (https://bitbucket.org/tortoisehg/files/downloads/TortoiseHg-4.5.0-mac-x64-qt4.dmg) takes between 6 to 8 seconds to load when I'm on tip and 12 to 14 seconds when I'm on revision 500000.

Opening the repository with thg 4.5 Qt5 (https://bitbucket.org/tortoisehg/files/downloads/TortoiseHg-4.5.0-mac-x64-qt4.dmg) takes forever when I'm on tip or not (more than 1 hour).

In both cases, the graphopt option has been set.

I've tried to diagnosticate it with the showstack extension and it seems that https://bitbucket.org/tortoisehg/thg/src/d0648f267bec60191f6fe323a69b8cfb404a7189/tortoisehg/hgqt/repomodel.py?at=default&fileviewer=file-view-default#repomodel.py-565 is called for each row in the Qt5 version but not in the Qt4 version.

I tried adding a traceback, but the traceback are not very helpful. I got two different tracebacks:

File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 249, in _runcatch
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 340, in runcommand
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 391, in _runcommand
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 345, in checkargs
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 339, in <lambda>
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/qtapp.py", line 471, in __call__
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 261, in _initView
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 860, in _updateRepoViewForModel
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 667, in defaultIndex
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 586, in flags

and

File ".../TortoiseHg45qt4.app/Contents/Resources/__boot__.py", line 82, in _run
File ".../TortoiseHg45qt4.app/Contents/Resources/thg.py", line 116, in <module>
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 48, in dispatch
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 249, in _runcatch
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 340, in runcommand
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 391, in _runcommand
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 345, in checkargs
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 339, in <lambda>
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/qtapp.py", line 471, in __call__
File ".../TortoiseHg45qt4.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 586, in flags

Both tracebacks seems to be missing the frames in PyQt.

I then tried to add a debug line:

diff --git a/tortoisehg/hgqt/repomodel.py b/tortoisehg/hgqt/repomodel.py
--- a/tortoisehg/hgqt/repomodel.py
+++ b/tortoisehg/hgqt/repomodel.py
@@ -567,6 +567,7 @@ class HgRepoListModel(QAbstractTableMode
         if not index.isValid():
             return flags
         row = index.row()
+        print("Flags", row)
         if row >= len(self.graph) and not self.repo.ui.debugflag:
             # TODO: should not happen; internal data went wrong (issue #754)
             return Qt.NoItemFlags

Running with this debug line on the Qt4 version output these lines:

('Flags', 25864) * 2 # The first line is repeated 2 times
('Flags', 25855) * 17 # This line is repeated 17 times
('Flags', 25856) * 17
('Flags', 25857) * 17
...
QPainter::begin: Paint device returned engine == 0, type: 2
QPainter::setCompositionMode: Painter not active
('Flags', 25855) * 3
('Flags', 25856) * 3
('Flags', 25857) * 3
('Flags', 25858) * 3
...

It generates ~300 lines of output but ends-up loading.

Running the Qt5 version is different. The traceback are similar (lines are different because I tried adding more or less lines in one version):

File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 249, in _runcatch
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 340, in runcommand
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 391, in _runcommand
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 345, in checkargs
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 339, in <lambda>
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/qtapp.py", line 471, in __call__
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 261, in _initView
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 860, in _updateRepoViewForModel
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 663, in defaultIndex
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 582, in flags

and another one that is different:

File ".../TortoiseHg45qt5.app/Contents/Resources/__boot__.py", line 82, in _run
File ".../TortoiseHg45qt5.app/Contents/Resources/thg.py", line 116, in <module>
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 48, in dispatch
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 249, in _runcatch
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 340, in runcommand
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 391, in _runcommand
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 345, in checkargs
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/run.py", line 339, in <lambda>
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/qtapp.py", line 471, in __call__
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 261, in _initView
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repowidget.py", line 862, in _updateRepoViewForModel
File ".../TortoiseHg45qt5.app/Contents/Resources/lib/python2.7/tortoisehg/hgqt/repomodel.py", line 582, in flags

The output seems to show that it's trying to render every rows at launch:

('Flags', 0) * 2 # The first line is repeated 2 times
('Flags', 1) * 2 # This line is repeated 2 times
('Flags', 2) * 2
('Flags', 3) * 2
...

I tried diffing the Qt4 and Qt5 versions but nothing seems to explain this difference, could it be because of PyQt4 vs PyQt5?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking