Sunday, January 18, 2009

The EMF Ultra Slim Diet

Are your objects feeling bloated? When you look in the memory analyzer, do unsightly bulges around the heap upset you? Do embarrassing OutOfMemory exceptions mar your social life? Well hide in shame no longer. With the new EMF Ultra Slim diet, you can quickly shed those unwanted bytes to a reveal a new and slimmer you. That's right, this is not a gimmick. Go to your GenModel now, find the "Root Extends Class" property, and enter the special promotional code below.


Then regenerate your model, sit back, relax, and let EMF do all the work. Unlike other fad diets, with EMF Ultra Slim, there is no risk of nausea, hair loss, depression, insanity, or premature death because no drugs are involved. Of course smaller objects have to work harder to get the same job done, so you may experience a small decrease in performance. If this disturbs you in the slightest, immediately stop the treatment, or better yet, take the steps outlined below to allocate the fields you really need to get the most out of life.

Please note that Ecore itself has taken the EMF Ultra Slim challenge so extenders of Ecore may notice that the eContainerFeatureID has disappeared, unless of course they too take the EMF Ultra Slim challenge themselves, in which case, references to this field will vanish along with the unsightly extra bytes it consumed. If this disturbs you, recall that I've repeatedly explained that extending Ecore is done at your own risk because binary compatibility of the implementation classes is not guaranteed. If you're feeling inclined to complain about that, please address all correspondence to Hello!@DoILookLikeICare?.com and prepare for a long wait because you're more likely to see the moss in this picture grow than to get a response.


How does this copyrighted new miracle treatment work without the aid of drugs? The wonders of open source reveals all. MinimalEObjectImpl has only two fields: an int eFlags field and an Object eStorage field; they are private, so I can change them in the future. The flags field is used to represent three things: whether notifications should be delivered, the container feature ID, as well as bits to indicate what's in the storage field. It's designed so that the field needs no initialization, i.e., the default value of 0 represents the correct ground state. Additional values, such as the container, adapters, dynamic class, dynamic settings, proxy URI, and resource are maintained in the storage field. If only one such value is needed, it's stored directly in the storage field. If more than one is needed, an array of objects is allocated to hold all the required values.

But wait, there's more! The adapters list is no longer stored as a list. It's stored as an array with a wrapper list being allocated only as needed. Not only that, if this array has the same contents as that of the container, the array of the container is shared. This fits very nicely with a common pattern of usage where all objects in a containment tree share the same adapters. It's a thing of beauty.


So what if you decide really want a field all the time for some specific value because you know your objects will always have it and you'd like the storage field itself not to end up allocating an array to hold multiple values. Worry not. By overriding two or three simple methods in your derived class, you can make that design choice yourself. The nested Container class of MinimalEObjectImpl does exactly that, i.e., it allocates a field to store the container. After all, most objects are contained by other objects so having a field for this is a good thing.

So what will this fantastic new therapy cost you? Not a penny, just the time it takes for one simple treatment. Of course generous donations to Eclipse will be most welcome. Don't forget to mention EMF Ultra Slim when professing your undying gratitude to Eclipse; in addition to a fast mirror, you'll receive a special reusable "fast help" coupon that you can use in the EMF newsgroup. As a footnote, MinimalEObjectImpl is the very first file I've ever committed that actually contains my name: "Copyright (c) 2009 Ed Merks and others."

10 comments:

Anonymous said...

What a great offer! Are operators standing by?

You may want to adjust your sales pitch slightly, though, and say "Root Extends Class" instead of "Root Extends Interface".

Also, for those stubborn types who have ignored your good advice and extended Ecore, do they really need to take the EMF Ultra Slim challenge themselves? I thought that they can maintain their unhealthy implementation style but, as long as they regenerate their code, those pesky eContainerFeatureID references will still disappear.

Ed Merks said...

Dave,

Thanks for the proof reading. I've made the correction.

Indeed Ecore extenders only need to regenerate and of course the classes that extend Ecore will automatically have the new base class. So yes, they can choose not to use the new base class for their other classes.

Anonymous said...

Hope that while writing this post, you were not on drugs ;-)

Nevertheless, well done!

Madhu said...

Ed says "Of course smaller objects have to work harder to get the same job done, so you may experience a small decrease in performance."

My question "Do we need to focus on implementations which will affect the performance?"

Especially when memory is getting cheaper, but high performance is expected. Moreover an application with less performance, even if its memory footprint is less, hardly got any chance to survive in the new world.

Java removed 'goto' statement so that developers will never dare to think about using it again. In similar lines, an option for a low performance implementation in EMF can tempt EMF users to go for it.

Madhu
http://mksamuel.blogspot.com/

Ed Merks said...

Madhu,

By allocating fields as desired, any specific performance/space trade-off is possible and the new approach is much more flexible than the "properties holder" approach of the past because it's trivially simple to deal with each field separately.

While what you say seems obvious on the surface, deep down it's not entirely so one sided. Firstly, a big bloated heap does tend to slow things down. Secondly, the size of a Java heap is limited; I'm not sure that's the case with 64 bit, but certainly with 32 bit, a 2G heap is the max, even if you have 4G of physical memory. I often joke that Java isn't scalable for this reason!

An application that's fast for small models but can't run because the heap is exhausted for big models is making a bad trade-off. As a framework provider, I must ensure that clients themselves are in a better position to choose the balance point.

Madhu said...

Thanks for the comments Ed.

Benjamin Cabé said...

Ed,
How many bytes per EObject are actually saved using the brand new MinimalEObject impl?
Thanks for this really cool diet :)

Ed Merks said...

Benjamin,

A lot of the detailed analysis is in How Big is EObject. It's not easy to give just a trivial answer because a lot depends on whether there are adapters, whether you've called eContents(), whether it's contained directly by a resource, and so on. Worst case kinds of numbers are 124 bytes reduced to 16 bytes.

Robert Moloney said...

I have changed my model to now use EMF Ultra Thin. Is it possible that there is now memory improvement?

Unknown said...

Even though this is an old post ... Thanks Ed for this wonderful diet - really works incredibly!