Всем привет! Наша команда разрабатывает IDE для работы с API TestMace. В одной из наших предыдущих статей читатели указывали на непомерно большое потребление памяти electron-приложений. Что ж, настало время цифр :) В данной статье автор оценивает потребление памяти однооконных приложений, написанных с использованием различных тулкитов. Приятного чтения!
Находясь в поисках идеального набора инструментов для создания GUI, я решил измерить объём занимаемой ими памяти.
По сути, я хотел выяснить, какой из них требует наименьшее количество памяти для программы, состоящей из одного пустого окна. В этой статье я расскажу о полученных результатах.
Дисклеймер
В данной статье приводятся данные о занимаемой программой памяти при использовании различных инструментов, фреймворков и библиотек для создания GUI на Linux. Все измерения сделаны на одном и том же компьютере с Ubuntu 19.04 (Disco Dingo) x86_64 с помощью программы Ksysguard, предоставляющей данные о потребляемой приложениями собственной памяти. Я не переустанавливал систему специально для проведения теста. Он был выполнен на моей повидавшей виды Ubuntu, на которой уже были установлены разного рода пакеты, что могло повлиять/исказить результаты.
Для некоторых инструментов я даже добавил измерения, полученные на Windows 10, которые вряд ли можно сравнивать с линуксовскими, но посмотреть интересно.
Хочу заметить, что мои измерения не представляют научной ценности. Имея другие исходные данные, вы можете получить совершенно другие результаты.
Не так просто, как кажется
Так что же нам необходимо измерить? Виртуальную память (VSZ)? Резидентная память (RSS)? Собственная RSS? Разделяемая RSS?
Если коротко, то... я считаю, что при сравнении двух одинаковых программ, разработанных с использованием разных наборов инструментов, правильнее всего будет измерить объем занимаемой процессом собственной памяти с smaps. Ksysguard использует smaps при выводе подробной информации о памяти. Однако с самого начала в своём эксперименте я использовал данные из панели потребления RAM по умолчанию, и только потом мне стало известно, что smaps дают более точные цифры. В целях обеспечения согласованности данных я использовал информацию из дефолтной панели RAM для всех представленных в списке инструментов, хотя, скорее всего, при использовании интерфейса с подробным описанием потребления памяти можно было бы видеть аналогичную ситуацию.
Если подробнее, то... в данной статье мне не хватило бы места на уроки по управлению памятью в Linux, да и к тому же уже существует множество достойных материалов на эту тему: ELC: How much memory are applications really using?, The /proc Filesystem, proc — process information pseudo-filesystem, Linux Memory Management Overview, Memory Management
Список инструментов и их показатели памяти
Ни слова больше. Вот мои результаты:
GUI тулкит | Собственная память (MB) | Замечания |
xcb | 0.132 | |
xlib | 0.156 | |
nuklear (rawfb) | 0.624 | не увеличивает потребляемую Xorg память |
xforms | 0.765 | |
WINAPI (Win10) | 1.00 | на 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,4 Мб + 1,8 Мб памяти Xorg |
WINAPI (WINE) | 2.30 | |
LCL (customdrawn) | 2.50 | |
Gtk+2 | 2.80 | |
wxX11 | 3.00 | не готов к использованию в production |
libui | 4.00 | |
LCL (Gtk) | 4.50 | |
Gtk+3 | 5.00 | |
wxGtk3 | 6.00 | |
EFL | 7.20 | |
GLFW | 9.00 | |
JUCE | 10.00 | бинарник Projucer, окно не пустое |
Sciter | 10.00 | около 10 Мб, отсутствует Linux Scapp |
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 | на 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 | upd: на ранних стадиях разработки! |
Boost.UI | - | использует wxWidgets |
CEGUI | - | как это вообще собрать? :(? |
IUP | - | схож с wxWdigets, использует Gtk+ на Linux |
Lgi | - | использует Gtk+ 2 |
MiniGUI | - | не удалось выполнить сборку |
morda | - | не удалось выполнить сборку |
SFGUI | - | использует SFML |
TGUI | - | использует SFML |
Verdigris | - | использует Qt |
UPD (мои благодарности kirbyfan64sos): Flutter Desktop всё еще находится на ранних стадиях разработки, и все сборки являются отладочными. Это означает, что все профайлеры (вроде Observatory) активны, все утверждения отладки включены, а компилятор AoT отключён. Будет интересно перепроверить данные с использованием релизной сборки.
Не скажу, что меня поразили показатели Electron.
Вот с HorusUI я ожидал примерной цифры в 20 Мб, т. к. он использует OpenGL и режим немедленной отрисовки GUI. Не понимаю, почему цифра вышла больше.
Java-фреймворки Swing и JavaFX тоже показали интересные результаты. Они оба крайне ненасытны, и если вы не уверены, какой из них подошел бы для вашего нового Java-проекта, то кажется разумным остановить свой выбор на более удобном и современном фреймворке JavaFX, хотя и придется отсыпать ему чуть больше памяти. Но если память у вас на вес золота, то, конечно, выбирайте Swing.
Qt тоже показал весьма занятные цифры и оказался намного прожорливее большинства других популярных инструментов. Стоит заметить, что большая часть занимаемой им памяти — это объем, потребляемый драйвером amdgpu, установленным в моей системе. Может, это потому, что буферы OpenGL сохраняются локально. То же самое можно видеть с SDL2: программа без OpenGL потребляет 1,1 Мб, а с ним — целых 14 Мб.
WxWidgets и LCL заняли хорошие позиции в этом сравнении. Несмотря на то, что они представляют собой обертки над другими инструментами для GUI, затраты ресурсов у них минимальны. Мне импонирует мысль о возможности перевода бекенда с Gtk+, например, на Qt, тем самым гарантируя независимость от инструментов.
Также выделю Nuklear, просто потому, что, как мне кажется, у него очень крутой режим немедленной отрисовки GUI. Если вас не смущает использование «сырого» X11 фреймбуфера, ваше однооконное приложение будет занимать всего 0,624 Мб, что выглядит весьма впечатляюще.
Заключение
Если вы надеялись увидеть здесь какие-то обобщенные выводы, то, боюсь, я вынужден вас разочаровать.