By Richard Szibele
16 August, 2019
While searching for the "perfect" GUI toolkit/library I've started measuring the memory usage of the various toolkits and I'm going to share my results here.
I basically wanted to answer the question: which GUI toolkit has the smallest memory footprint for a program with an empty window.
This article provides an overview of the memory usages of various GUI toolkits, frameworks and libraries on Linux. All measurements were taken on the same Ubuntu 19.04 (Disco Dingo) x86_64 machine with the help of ksysguard, which gives us the private memory usage of the applications. I did not test the applications on a fresh Ubuntu installation, the installation which I tested them on already had development and other misc packages installed, which may or may not have affected/skewed the test results.
In a few cases I've even added some Windows 10 measurements into the mix, which one can't really compare to Linux memory usages, but they are clearly labeled as such.
These measurements are not scientific at all, and given a different setup you will more or less get different results.
What should we be measuring when comparing different GUI toolkits? virtual memory (VSZ)? resident set size (RSS)? private resident set size? shared resident set size?
The short answer: I believe private memory with smaps is a decent way to estimate memory usage of a process and is ideal when comparing two similar programs with different toolkits/libraries. ksysguard uses smaps in the detailed memory view.
However, I used the default memory view since the beginning and only later found out that smaps was a more accurate representation of memory usage. To keep the data consistent I continued to use the default memory view for all toolkits, though the data would likely show a similar trend when using the detailed view.
The long answer: ... is out of scope for this article, as I would have to explain Linux memory management and there are already great resources for that available: ELC: How much memory are applications really using?, The /proc Filesystem, proc - process information pseudo-filesystem, Linux Memory Management Overview, Memory Management
Without further ado, here are the results:
GUI Toolkit | priv. Mem. (MB) | Notes |
xcb | 0.132 | |
xlib | 0.156 | |
nuklear (rawfb) | 0.624 | does not increase xorg memory |
xforms | 0.765 | |
WINAPI (Win10) | 1.00 | on Windows 10 |
dlib | 1.10 | |
SDL2 (without opengl) | 1.10 | |
GDK | 1.20 | |
turbo vision | 1.30 | TUI |
nana | 1.40 | |
Motif | 1.50 | |
FLTK | 1.70 | |
MSEGui | 2.04 | |
FOX | 2.20 | |
nuklear (x11) | 2.20 | 0.4MB + 1.8MB xorg memory |
WINAPI (WINE) | 2.30 | |
LCL (customdrawn) | 2.50 | |
Gtk+2 | 2.80 | |
wxX11 | 3.00 | not production ready |
libui | 4.00 | |
LCL (Gtk) | 4.50 | |
Gtk+3 | 5.00 | |
wxGtk3 | 6.00 | |
EFL | 7.20 | |
GLFW | 9.00 | |
JUCE | 10.00 | projucer binary, not empty window |
Sciter | 10.00 | around 10MB, Linux Scapp missing |
LCUI | 11.00 | |
GLUI | 12.50 | |
SFML | 13.20 | |
nanogui | 14.00 | |
SDL | 14.00 | |
U++ | 14.00 | |
Agar | 15.00 | |
Dear ImGUI (SDL) | 15.30 | |
GuiLite | 15.80 | |
Dear ImGUI (SDL/Vulkan) | 16.50 | |
Mono WinForms | 16.564 | on Windows 10 |
Qt | 17.00 | |
Ultralight | 20.00 | |
revery | 23.50 | |
Java Swing | 59.30 | OpenJDK 12 |
electron | 74.60 | |
JavaFX | 80.00 | OpenJDK 12 |
horus_ui | 94.00 | |
Flutter Desktop | 98.00 | update: early development! |
Boost.UI | - | uses wxWidgets |
CEGUI | - | how does one build this :(? |
IUP | - | similar to wxWdigets, uses Gtk+ on Linux |
Lgi | - | uses Gtk+ 2 |
MiniGUI | - | build fails |
morda | - | build fails |
SFGUI | - | uses SFML |
TGUI | - | uses SFML |
Verdigris | - | uses Qt |
I was surprised to find out that Flutter was such a memory hog, seeing that it was initially intended to be a GUI framework for mobile phones.
Update (thanks kirbyfan64sos): Flutter Desktop is still in early development and all builds are debug builds. This means that profile tools are active (e.g. Observatory), debug assertions are all enabled and the AoT (ahead of time) compiler is disabled. It will be interesting to see the memory usage once release binaries are available.
I can't say I was surprised to find Electron up there with the hogs.
HorusUI was interesting in that I expected it to use around ~20MB, as it uses OpenGL and is an immediate mode GUI. No idea why it uses so much.
The Java GUI frameworks Swing and JavaFX are also interesting, they are both pretty heavyweight and if you're not sure if you should use Swing or JavaFX for your new Java project then it seems like it would make sense to just accept the little bit of extra bloat and use JavaFX, which is a lot nicer to work with and more modern. Or maybe not if you don't like the extra memory bloat.
Qt is also at an interesting spot, it's heavier than most other mainstream toolkits. One thing that's interesting about it, is that a large chunk of the memory used is due to the amdgpu driver on my system. Perhaps OpenGL buffers being stored locally? The same thing can be seen with SDL2, where the program without OpenGL support uses 1.1MB and the one with uses 14MB.
WxWidgets and LCL held their ground in this comparison. Even though they are wrappers around other GUI toolkits, the overhead seems to be minimal at best. I really like the idea of being able to switch the underlying backend from Gtk+ to Qt for instance, thereby guaranteeing toolkit independence.
Nuklear gets a special mention, simply because I think it's a pretty awesome immediate mode GUI. If you don't mind using a raw X11 framebuffer, then you can get a window up on the screen with 0.624MB, which is pretty impressive.
If you were hoping for some kind of conclusion, then I'm going to have to disappoint you.
← back