Tinymail does in 4mb what evolution does with 60mb

I told some people that I “will” prove that an e-mail client can load huge folders using very few memory. So I will prove it now.

Today tinymail can show the folders and subfolders of multiple accounts, it can show the message headers in a summary view and it can show the content of an E-mail picked from that view.

I did a session where I launch both evolution and tinymail from a cold start using the massif tool of valgrind. Both Evolution and Tinymail showed all the folders. Both evolution and tinymail gave a view of the message headers in the folder. Both evolution and tinymail viewed the last e-mail that appeared in the list. Using both evolution and tinymail I scrolled to the last message header and back to the first.

I do understand comparing tinymail with evolution might sound unfair. I do think a lot of the by evolution allocated memory is not just the non-trivial user interface stuff. In fact, by turning off my proxy design pattern tricks, I get surprisingly very similar memory usage results with tinymail.

Evolution used 60 megabytes of ram. Tinymail used 3 – 6 megabytes.

Both evolution and tinymail used camel. But that doesn’t mean that camel doesn’t need improvements. It certainly does.

At stage one the folders are being loaded. At stage two the (visible) message headers are loaded. And at stage three I was scrolling the message header summary view’s scrollbar down and up a bit. The tree stages where repeated on both tinymail and evolution.

Note that I’m uncertain about the three marked points on the evolution graph.

I am, however, certain about these three marked points (I did multiple valgrind measurements and disabled some steps to watch the memory status at known points in time).

I kindly invite people to reproduce these measurements. You can get a checkout of tinymail here. Use “valgrind –tool=massif tinymail or evolution”. Read this piece of source code to know how to create an account.

(I think) The biggest reason why evolution uses a lot memory is because of the CamelFolder instances that get delivered by camel_store_get_folder. I created a treemodel that uses proxy instances for this CamelFolder type. I made sure the real CamelFolder instance gets freed when it’s not used anymore.

For 50 folders that reduced the total amount of memory with ten megabytes. You can see that allocation peek in the valgrind massif report of tinymail. You can’t see it as clear in the evolution report because, well, it simply never gets freed. If you don’t load the folders in tinymail recursively (for example only the INBOX folder), the peek goes away. This proves that it’s indeed the allocation of all the CamelFolder instances (in fact I ironed that out to the very call to camel_store_get_folder, as I wanted to make sure it wasn’t my own code causing these allocations). I think a lot of evolutions memory goes into those CamelFolder instances.

So I was wrong when I said that it’s the camel_folder_get_uids function. As a solution, evolution could create a proxy class for CamelFolder and attempt to camel_object_unref the real folder instance as soon as possible. For a sample, take a look at how tinymail does it.

One thought on “Tinymail does in 4mb what evolution does with 60mb”

Comments are closed.