Poor performance of the Qt interface

Hello,

I’m building a ROOT-based Qt application and under certain circumstances I find it extremely slow.

The main part of the application is a TQtWidget instance showing various ROOT plots. The application is (to be) run on a remote machine. When I resize the window, it takes up to some 1 or 2 seconds for the canvas to redraw… First I thought it was because of a slow network connection, but it doesn’t quite explain it. When I replace the TQtWidget by a Qt class (QTextBrowser for instance), the performance improves by a great deal (the window is redrawn practically instantaneously). Would you know what causes this strange behavior?

I made a few test with the application run locally. Indeed, the response is much faster, but there is still a noticeable difference between TQtWidget and a Qt class (QTextBrowser). Would you know what causes this performance penalty? Would you know how to make it faster?

On the remote machine, the application is compiled across ROOT 5.24 and Qt 4.4.2. On my local machine, it is ROOT 5.25 (from svn) and Qt 4.5.2.

If you wished, I can send a simple code that demonstrates the issue.

Many thanks in advance, Kašpi.

[quote=“kaspi”]I’m building a ROOT-based Qt application [/quote] :smiley: [quote=“kaspi”]and under certain circumstances I find it extremely slow. [/quote] :cry: :blush: [quote=“kaspi”]The main part of the application is a TQtWidget instance showing various ROOT plots. The application is (to be) run on a remote machine. When I resize the window, [/quote] “I” stands for the human operator resizing the widget with the mouse “press and drag” gestures doesn’t it ?[quote=“kaspi”] it takes up to some 1 or 2 seconds for the canvas to redraw… [/quote]I would like to stop at this point and would like you to elaborate a little bit more.

Do you see the poor performance during very resizing ? If the naswer is “yes” I would like to see your main widget layout.
Do you see the same problem from ANY X-terminal or just from your concrete desktop?

[quote=“kaspi”]When I replace the TQtWidget by a Qt class (QTextBrowser for instance), the performance improves by a great deal (the window is redrawn practically instantaneously). [/quote] It does not say anything because QTextBrowser doesn’t need to call TCanvas::Update()/ TCanvas::ResizePad() to render the ROOT objects . Can you observe the spike of the remote machine CPU load when you are resizing the widget ? [quote=“kaspi”]If you wished, I can send a simple code that demonstrates the issue. [/quote] Yes, I do. Please, send the code

Thank you, Valeri

Many thanks for your quick response :slight_smile:

Exactly, a human being grabs the lower right-hand side corner of the window and moves it forth and back. Or a human being clicks the maximize/restore button.

In fact the time quite varies, but very often it is inconveniently long.

I don’t understand what you mean by “very resizing”. Anyway, I’ve extracted the relevant part of the application and you can find it in the tarball attached (together with makefile and a script to set environment variables).

I’ve made quite a few tests. With 2 servers: our experiment machine (4 dualcore processors) and lxplus - both running 64bit SLC4. And with 2 clients: my desktop - 32bit ArchLinux/KDE and my colleague’s desktop 32bit SLC4/Gnome. The performance exhibits still the same issue, however, it tends to be faster when run on lxplus.

I partly agree. My argument was to prove that it was not a slow network connection causing the problem. Maybe here, I should remark that I cannot see much of difference between empty and filled TCanvas.

[quote=“valeri”]
Can you observe the spike of the remote machine CPU load when you are resizing the widget ?[/quote]

Yes, when resizing (forth and back), the application takes some 20% of processor capacity and so does one sshd deamon (same for both servers I tried).

One more observation - the resizing is not the only lengthy operation. When I right-click on an axis to get the pop-up menu, I first see a gray rectangle, some 10s after I get text in it, some 10s after the menu starts to highlight the line under cursor (with a considerable delay when moving the cursor fast) and eventually when I click on an item it again takes quite some time before it actually does something. It this case the CPU load stays low until I start to move mouse cursor over the menu, then it raises to some 6%. The same holds for one of the sshd’s. Is there a reason for such a behavior?

Many thanks, Kašpi.
qtTestSimple.tar.gz (1.01 KB)

[quote=“kaspi”]… a human being grabs the lower right-hand side corner of the window and moves it forth and back. Or a human being clicks the maximize/restore button.[quote=“kaspi”]it takes up to some 1 or 2 seconds for the canvas to redraw[/quote]In fact the time quite varies, but very often it is inconveniently long.[/quote] Thank you very much your test program and report.

Event though I did not get the delay time anywhere close to your “up to some 1 or 2 second” I do agree the resizing time is “is inconveniently long”. I do not know the exact reason for such delay yet.

The embedded TCanvas is painted 3 times during resizing. It was introduced to optimize the resizing experience under Qt3 on Win32 platform.

The first rendering has to be performed at the very beginning of the sizing. The last one is done after the user releases the mouse button to polish the final view. I’ll need to evaluate (over weekend) the algorithm to see whether it is still needed under Qt4 and whether it contributes to the delay you are complaining about. My impression (to be tested yet) under Qt4 all 3 re-renderings happen near simultaneously at the end of the move making the issue worse.

What about your comparison with the QTextBrowser.

I would like to mention that even the “empty TCanvas“ is not empty from the GUI layer stand point. The “empty TCanvas” does contain the empty TPad and 2 “empty” TCanvas buffers. Each one has to be a real pixmap object. Each one has to be as large as the widget dimension and they has to be rendered by X11 server. In case of the resizing, each pixmap has to be deleted, recreated, and refilled to reflect the new widget size via TPad::ResizePad method. This means that resizing of the ROOT Canvas will always be quite expansive and this fact has to be taken account for the GUI design.

The low level layer doesn’t see any difference between the filled and empty TPad. In both cases it is to render one and the same thing, just pixmap (2 dimensional array of the colored pixels).

[quote=“kaspi”] When I right-click on an axis to get the pop-up menu, I first see a gray rectangle, some 10s after I get text in it, some 10s after the menu starts to highlight the line under cursor (with a considerable delay when moving the cursor fast) [/quote]Can you try
root.bnl.gov/QtRoot/How2Install4 … complement to see whether this particular problem persists?

Many thanks for your investigation and your explanations. I really appreciate it!

Thanks, Kašpi.

[quote=“fine”][quote=“kaspi”] When I right-click on an axis to get the pop-up menu, I first see a gray rectangle, some 10s after I get text in it, some 10s after the menu starts to highlight the line under cursor (with a considerable delay when moving the cursor fast) [/quote]Can you try
root.bnl.gov/QtRoot/How2Install4 … complement to see whether this particular problem persists?[/quote]

I’ve just tried it, but I guess that I did not use it correctly. It is not clear to me how to use the QtRoot in a ROOT-based Qt application. What I did was simply to link my application against libGQt from your QtRoot instead from the “normal” ROOT. The net result is that canvases (including embedded objects) stopped to react on right-click… What am I doing wrong?

Thanks again, Kašpi.

[quote=“kaspi”] . . I’ve just tried it, but I guess that I did not use it correctly. … What am I doing wrong?[/quote]I suspect you did not define the correct plugin via “.rootrc” ROOT resource file. Mmm, I have to highlight this. Anyway, the first thing to do is to run the qtExamples test suite (each test comes with the local version of “.rootrc”). Did you try that?

cd qtExamples qmake makeI am going to add a dedicated section “test” to How2Install page. Thank you for the hint.

[quote=“kaspi”]… the CPU load stays low until I start to move mouse cursor over the menu, then it raises to some 6%. The same holds for one of the sshd’s. Is there a reason for such a behavior?
[/quote]This is the normal response to the mouse movement.
You should see it with any GUI application.

What about ROOT, you should take in account the fact that the ROOT is to invoke TObject:: DistancetoPrimitive method for each object included into the TCanvas / TPad for each mouse “move “ event. Many ROOT classes provide its own implementation of that virtual method and many of them are "CPU intensive”. Try grep DistancetoPrimitive $ROOTSYS/include/*to see what I meant.

[quote=“fine”][quote=“kaspi”] . . I’ve just tried it, but I guess that I did not use it correctly. … What am I doing wrong?[/quote]I suspect you did not define the correct plugin via “.rootrc” ROOT resource file. Mmm, I have to highlight this. Anyway, the first thing to do is to run the qtExamples test suite (each test comes with the local version of “.rootrc”). Did you try that?
[/quote]

You’re right. I realized that a few moments after having send the email. In fact, the code which is in the plugin file P*.C can be put directly into application code - one avoids the necessity of the .rootrc file in this way.

I find the QtRoot extremely useful, it really improves the performance of our application :smiley: Is it a part of the official ROOT or is it rather your own project? It looks to me that some modules (qt) can be found in the official ROOT SVN, but others not. In case it is your own project, do you align your development somehow with ROOT releases? And how about your license? Is there some more documentation? For instance, I wonder what is the difference between qtgui and qtroot modules - several files seem almost identical in both packages.

Many thanks for your support,

Kašpi.

[quote=“kaspi”]I find the QtRoot extremely useful[/quote] :smiley: [quote=“kaspi”]Is it a part of the official ROOT or is it rather your own project?[/quote]That was explained about 2 dozen times on this list, published and root.bnl.gov/QtRoot/QtRoot.html#what

[quote=“kaspi”]It looks to me that some modules (qt) can be found in the official ROOT SVN, but others not. [/quote]“qt” ( lists.bnl.gov/pipermail/qt-root-l/ . I am writting a new version of Qt Chapter for the ROOT User’s Guide :unamused: I do provide a bunch of the “HelloWord” working examples under qtExamples directory. Each example is usually provided with README. [quote=“kaspi”]For instance, I wonder what is the difference between qtgui and qtroot modules - several files seem almost identical in both packages.[/quote]Yes, correct. The packages are mutual exclusive. Both packages are to provide some implementation of one and the same ROOT interfaces. qtgui - is full-fledge QtRoot interface, you get it when you define “Gui.Factory qtgui” qtroot is stripped version done by Rene’s demand to provide the minimum Qt functionality. You get it when you define “Gui.Factory qt”. To remove the duplications from “qtgui” I need the last version of qtroot to be approved by Rene and merged with CERN SVN.

Many thanks for your very kind and helpful support. I really appreciate it :smiley:

Kašpi