What are the performance implications of using an immediate-mode GUI compared to a retained-mode GUI?

Solution 1:

Since there seems to be some interest in this question still (judging by the views), I thought I might as well post an update.

I ended up implementing an immediate-mode GUI as my master’s thesis, and have some numbers in on the performance. The gist is:

It's fine - quality of implementation dominates, not systematic characteristics.

Compared to many other existing retained mode GUIs, my immediate mode implementation generally performs a lot faster. The theoretical performance differences between the paradigms are eclipsed by the fact that most GUIs are horribly unoptimized. Overall, imgui is a completely viable approach to creating a GUI that responds fast and does not drain the battery.

I created a Spotify clone with about 50% of the UI elements, and rendering a single frame was in the microsecond range. In fact, the application consistently used less than 400 μs for a single frame. With V-Sync enabled on a 60 Hz monitor, this equates to roughly 3% CPU load on a single core (400 μs per 16 ms) for a naive implementation. Furthermore, a decent chunk of these 400 μs were caused by constant factors that wouldn’t increase the load with more UI elements (e.g., receiving input or setting up GPU state that doesn’t scale with UI complexity).

The perfectionist in me still disliked the fact that a GUI that did nothing was consuming cycles, but the upsides were tremendous: When the GUI was being heavily interacted with, or when the window was being resized, it was still hitting 400 μs! This blows many existing retained-mode GUIs out of the water. Try resizing Spotify, Windows Explorer, Visual Studio, or basically any other desktop application, and see how it reacts, to understand what I mean. My guess would be that Spotify goes down to about 2 fps on my PC when resizing.

And changing the UI is basically free. If you display a hundred buttons in one frame, and then replace them all with textboxes in the next, there is still no difference to the performance. Retained-mode GUIs tend to struggle in such scenarios.

Three more thoughts:

  • Most of the time is spent on text rendering, the rest is close to irrelevant. If you want to heavily optimize, this is going to be the thing to focus on. But even with little optimization, it can be made decent.

  • I doubt that the vast difference in performance can be explained only—or even at all—by the difference between the retained and immediate modes. For example, Spotify uses a Web stack for UI; that’s bound to be slow.

    I guess, WPF, Win32, and the likes are just slow because they can get away with it, or because they were optimized for completely different hardware than the one we use nowadays. They also do more, of course, but not remotely enough to justify the difference.

  • I’m sure you could make a retained-mode GUI that is a lot faster than my immediate-mode GUI. There is just little incentive for it in general, which is a little sad, to be honest; I like efficient things.

Update

Since a couple of people asked, I’ve decided to release my thesis.

Please be aware that you will be looking at something that was not meant for public release and doesn’t pass my personal lowest quality expectations for a publicly released piece of software (which is why I hadn’t released it in the first place). So please only use it for educational purposes and not for building actual software with it. I won’t be supporting it, either.

The download includes the thesis itself (in German!), some pre-built executables for Windows, and the source code (in C++):

https://1drv.ms/u/s!AsdZfH5hzKtp9zy1YZtHgeSMApOp?e=FbxLUs

Have fun!