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

Windows

Firefox with Text Tab - RAM Usage: 514MB

Firefox

Intellij IDEA Just Opened - RAM Usage: 848MB

IDEA

Discord - RAM Usage: 503.1MB

Discord

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.

Mockup Interface

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:

Results

After implementing the note application in each of the toolkits I reached the following conclusions:

And now the main point of the tests, RAM consumption:

GTK - 26.54MB

GTK Notes

Swing - 55.60MB

Swing Notes

FLTK - 9.84MB

FLTK Notes

Nuklear + X11 - 3.9MB

Nuklear + X11 Notes

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:

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.