Tuesday, March 18, 2008

Tuning ELists

Just solved a serious performance problem. I programmtically constructed a rather big EMF model. It took ages so I started a profiler: Most of the time was spend in the BasicEList.contains(EObject) method. 

This is due to the fact that the corresponding EReferences have the unique flag set to true. EMF makes sure each element appears only once in the list of that reference. This is good, but performs poor for big growing lists.

As I construct the model from scratch I can make sure there will be no duplicates. So instead of
parent.getFeature().add(child);
I cast to BasicEList and call
((BasicEList<EObject>) parent.getFeature()).addUnique(child);

In my case, that reduced the execution time to a fifth !

5 comments:

Boris Gruschko said...

Hi Jan,

what happens, if it's not a BasicEList ? Afaik, everyone is free to substitute the EList implementation in his MM code. In the EMF world, it is ;)

Cheers,
Boris

Jan Köhnlein said...

Of course, everyone can implement their own ELists. This is an example on how to tune an application that is using the standard EMF implementation. Note that the described performance penalty is also specific to the EMF standard implementation.

Generally, I'd expect performance optimization to be in a way specific to some implementation in 90% of the cases.

Boris Gruschko said...

What happens, if someone will use the proposed implementation in his tool, based on your meta-model and then you change the EList implementation ?

Or better still, if someone uses instances of multiple meta-models ?

Anyway, the upcasting of public interfaces to internal implementations appears to be a dangerous advise to give.

Jan Köhnlein said...

This has never been meant to be a common advice, like "always do it that way". The original reason for my post was that I was astonished to have a 80% performance boost. And I think I emphasized the very special conditions of my case.

I clearly see your point that casting can be a very dangerous thing, but from my experience - especially within eclipse development - you are often forced to do such casts to get your job done at all. Of course your code should handle exceptions gracefully.

But, believe it or not, BasicEList is *public* API. EMF allows you to do a lot of things like these. I understand your concerns because we tried to implement our own EMF compliant repository and more or less failed because of EMF's versatility. You won't ever be 100% compatible unless you are using the standard EMF implementation. I'd be the first to vote for the definition of several levels of EMF compliance.

Christopher Daniel said...

What do you mean by "large EMF Model"?