Minimize Memory
Because I often forget stuff I want to remember, I built some simple shell scripts to register notes and search them later.
After having the shell scripts for some time I decided to build them a simple UI. I tried the gtk but after checking the RAM usage I thought it was consuming too much. With this in mind I tested some other graphical toolkits to check their resources usage.
Around that time a friend called me to make a presentation at ENEI 2019. Since I already had comparisons of the RAM usage of multiple graphical toolkits I proposed a presentation about that.
After he accepted the theme I started preparing the content in a more structured way.
Literate Programming
At this time I had heard about a technique created by Donald Knuth called Literate Programming. This changes the programming paradigm to describe the program in a natural language like english with snippets of the traditional source code along the descriptions.
We can then compile this english document with embedded code to generate the final documentation and the program source code.
With this approach the programmer turns into a book writer who is trying to explain the program to other people, and the book by the way also generates the final program!
After reading about this topic I thought it could be nice for bigger programs to be more maintainable, but the most straight forward application I saw was to make tutorials and presentations.
So with this in mind I decided to make all the presentation code using this technique in order to in the end providing a document with all the description while also being the implementation.
Compiler
After checking for tools that support literate programming I found the main ones CWEB created by Knuth and the noweb. CWEB supports C, C++ and Java while noweb supports a big list of languages. The documents in both are built using LaTeX with some special marking. Syntax example:
@ Here's the code to open the file. A special trick allows us to
handle input from |stdin| when no name is given.
Recall that the file descriptor to |stdin| is~0; that's what we
use as the default initial value.
@<Variabl...@>=
int fd=0; /* file descriptor, initialized to |stdin| */
@ @d READ_ONLY 0 /* read access code for system |open| routine */
@<If a file...@>=
if (file_count>0 && (fd=open(*(++argv),READ_ONLY))<0) {
fprintf (stderr, "%s: cannot open file %s\n", prog_name, *argv);
@.cannot open file@>
status|=cannot_open_file;
file_count--;
continue;
}
While I already made multiple reports using LaTeX I would prefer to have a simpler syntax, so I kept looking for more tools and eventually found the Literate project with the Lit compiler.
The syntax is markdown with just some simple delimiters for the management of code snippets. Looked simpler and the resulting documents also looked nice so I decided to try it. Syntax Example:
@s
The grand totals must be initialized to zero at the beginning of the program.
If we made these variables local to main, we would have to do this initialization
explicitly however, C’s globals are automatically zeroed.
--- Global variables +=
long tot_word_count, tot_line_count, tot_char_count;
/* total number of words, lines and chars */
---
Main Problem
After watching the RAM consumption of the graphical toolkits I started measuring the consumption of multiple common applications/systems:
Windows 10 Just Booted - RAM Usage: 2.4GB
Firefox with Text Tab - RAM Usage: 514MB
Intellij IDEA Just Opened - RAM Usage: 848MB
Discord - RAM Usage: 503.1MB
A OpenBSD server when installed occupies 20MB of RAM. Of course this is a unfair comparison since something like Windows have a graphical environment. But is all this difference only from the graphical environment?
With this in mind I created some rules for benchmarking and comparing the graphical toolkits by implementing the note application in each of them.
How I Tested
First I decided the interface I wanted to have implemented in each of the toolkits.
Since each pixel in the monitor occupies memory I defined a fixed window size of 400x300.
Also I made sure that the insertion and filtering where done by the shell scripts and only the UI was done using the toolkits so we can measure just the toolkit resources usage.
Selected Toolkits
I didn’t have time to test every toolkit so I selected some of the more common and some to try to reach lower memory usages, the selected ones were:
- GTK - Most graphical environments in linux use gtk.
- Swing - Java based graphical toolkit.
- FLTK - Focus in being the most lightweight possible.
- Nuklear + X11 - Immediate mode graphical user interface toolkit, provides only commands to draw primitives as output and doesn’t implement a drawing backend. This way we need to supply our own backend with the primitives implementation, in this case X11 was used.
Results
After implementing the note application in each of the toolkits I reached the following conclusions:
- GTK is nice to use and has a really well prepared documentation. I used the pure C approach but xml or a GUI editor could be used.
- Swing documentation is somewhat difficult no navigate. Swing didn’t had much examples to follow.
- FLTK drawing was quite simple to start, but after that I needed multiple manual calculations to align each of the elements.
- Nuklear documentation is lacking some content, to use it I needed to read the lib code and in this case the X11 implementation.
And now the main point of the tests, RAM consumption:
GTK - 26.54MB
Swing - 55.60MB
FLTK - 9.84MB
Nuklear + X11 - 3.9MB
The winner in size was the Nuklear, in appearance my favorite was also nuklear and in simplicity of use gtk won thanks to their nice documentation and extra tools.
Other experiments
While I was testing this I also checked other tools but didn’t had the time to build the notes application with them. Anyway I will present here the RAM usage of their “Hello World” implementations:
- Electron - 125MB with resources usage getting bigger over time.
- Tekui - 9.8MB using Lua as scripting language and with support for styling with CSS(Looks really nice).
- Wayland Client - 868KB with a framebuffer with 400x300.
Literate Programming Documentation
Literate programming was also really interesting, making me think better about each choice of implementation and architecture, while explaining the why and the how of each step.
To check the book with the documentation/code generated by the literate programming technique check the page.
NOTE: The nuklear implementation is missing in the literate programming generated docs because I implemented it latter and since was testing the nuklear lib I didn’t add it to the literate way.
Repository
If you want to see the code or the presentation check here.
Other
If you want to receive updates when there are new games or development stories join the mailing list