Bug 528925 - [stereotypes] The application of a stereotype is very slow compared to element creation
Summary: [stereotypes] The application of a stereotype is very slow compared to elemen...
Status: CLOSED FIXED
Alias: None
Product: MDT.UML2
Classification: Modeling
Component: Core (show other bugs)
Version: 5.3.0   Edit
Hardware: All All
: P2 enhancement (vote)
Target Milestone: 5.4.0   Edit
Assignee: Camille Letavernier CLA
QA Contact:
URL:
Whiteboard:
Keywords: helpwanted
Depends on:
Blocks: 529945 530156
  Show dependency tree
 
Reported: 2017-12-18 17:37 EST by Ansgar Radermacher CLA
Modified: 2018-06-28 11:38 EDT (History)
5 users (show)

See Also:
Kenn.Hussey: iplog+


Attachments
Domain Architecture screenshot (1023.51 KB, image/gif)
2018-06-27 17:08 EDT, Toni Siljamäki CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ansgar Radermacher CLA 2017-12-18 17:37:44 EST
I've done a few benchmarks using a photon environment (UML5.3.0) and the the results seem to indicate that the application of a stereotype is very costly compared to the element (in this case, a Class) creation: 2000 classes can be created in less than 1 second, compared to ~ 15 seconds when applying a stereotype.
Interestingly, the "low-level" stereotype application via the steps below only added a negligible overhead to the element creation compared to using the stereotype application helper with the right EClass.

Low-level steps#:
1. calling the factory method of the stereotype (static profile)
2. adding the returned EObject to the model resource
3. setting the base element via the operation setBase_Class (the example stereotype extended Class).

It seems that the generic UMLUtil.setBaseElement operation called by the stereotype application handler is very costly, as it loops over all structural features to find the baseClass attribute.
Comment 1 Kenn Hussey CLA 2017-12-19 08:04:36 EST
Thanks for the bug report. Suggestions on how to improve the performance would be greatly appreciated; contributions would be appreciated even more. :)
Comment 2 Camille Letavernier CLA 2018-01-18 09:17:35 EST
The main issue in UMLUtil is that there are some frequent switches between the Definition (Ecore world) and the NamedElement (UML world). And sometimes, we start from a method taking a Stereotype as a parameter, compute its definition and forget about the stereotype, then compute the stereotype again from the definition.

This is especially the case for the "Apply stereotype" method, which takes the Stereotype as a parameter, but doesn't pass it to the StereotypeApplicationHelper. Later, in the setBaseElement method, UMLUtil has to search again for the Stereotype (Just to make sure it exists - even though it was the initial parameter in the call stack)

Iterating over the structural features to find the base_X one is also costly (Especially since it iterates over all features, including EAttributes, rather than only EReferences), but it's minor compared to the other issues. When  fixing these issues, Element#applyStereotype is only 2x slower than the ideal case (Because UML still has to rely on the reflexive API, whereas the ideal case can directly reference the proper factory & directly set the correct base_X element. Also, the ideal case bypasses the Stereotype Application Helper, which could decide to store the stereotype application to a different location - so it actually breaks some features).
Comment 3 Kenn Hussey CLA 2018-01-18 09:36:06 EST
Thanks for the hints, Camille. It sounds like some method overloads (to pass computed values down the call stack) would help here; switching the base reference lookup to sift through references only is a trivial change.
Comment 4 Eclipse Genie CLA 2018-01-18 09:51:47 EST
New Gerrit change created: https://git.eclipse.org/r/115634
Comment 5 Camille Letavernier CLA 2018-01-18 10:00:04 EST
> New Gerrit change created: https://git.eclipse.org/r/115634

This patch applies the suggestions from Comment 2 and Comment 3

Note that the performance gain is not so important (10% in most cases, 40% in one specific test), and negligible in Papyrus for the test case in Bug 529945 (Because the cost of the transaction is much higher than the UMLUtil issues - although on very big models with smaller transactions [creating less elements, but in a bigger model], the proportions might change). What Ansgar observed with 15x slower results is actually due to the test Profile (SysML 1.4), which was not correctly registered to the generated_package extension point.

When using only the UML API (Create class + apply stereotype), the time goes from ~2500ms (Before the patch) to ~1500ms, so that's still an improvement. When adding Papyrus commands in the equation, we only go from 8700ms to 7900ms, but most of the time is spent in Transaction recording/Notifications processing
Comment 6 Ed Willink CLA 2018-01-18 10:03:04 EST
I'm concerned about how this impacts on OCL where EPackages etc are a pain but manageable. In particular I do not understand why a new extension point entry is needed. Surely analysis of the models referenced by the already existing extension points can find all the more deeply 'hidden' registrations.
Comment 7 Camille Letavernier CLA 2018-01-18 10:20:29 EST
>  Surely analysis of the models referenced by the already existing extension points can find all the more deeply 'hidden' registrations.

Which extension point(s) would you use to find a generated UML Profile/Package related to its Ecore definition? AFAIK, except for this extension point, they have no relationship
Comment 8 Kenn Hussey CLA 2018-01-18 10:29:25 EST
(In reply to comment #5)
> > New Gerrit change created: https://git.eclipse.org/r/115634
> 
> This patch applies the suggestions from Comment 2 and Comment 3

Thanks, Camille, I'll take a look as soon as I am able.
Comment 9 Ed Willink CLA 2018-01-18 10:43:47 EST
Looking at GIT\org.eclipse.ocl\plugins\org.eclipse.ocl.pivot.uml\plugin.xml

   <extension point="org.eclipse.emf.ecore.generated_package">
      <!-- @generated OCLforUML.profile -->
      <package
            uri="http://www.eclipse.org/ocl/2015/OCLforUML/1"
            class="org.eclipse.ocl.pivot.uml.internal.oclforuml.OCLforUMLPackage"
            genModel="model/OCLforUML.profile.genmodel"/>
   </extension>

gives me two analysis roots.

a) org.eclipse.ocl.pivot.uml.internal.oclforuml.OCLforUMLPackage takes me to Java code that can be analyzed by instantiating its eINSTANCE..

b) model/OCLforUML.profile.genmodel takes me to a model that I can load and so discover

  <foreignModel>OCLforUML.profile.uml</foreignModel>
  <genPackages xsi:type="genmodel:GenPackage" prefix="OCLforUML" basePackage="org.eclipse.ocl.pivot.uml.internal" disposableProviderFactory="true">
    <ecorePackage href="OCLforUML.ecore#/"/>

allowing analysis of OCLforUML.profile.uml and OCLforUML.ecore.

Surely everything is present in *.profile.uml?
Comment 10 Camille Letavernier CLA 2018-01-18 10:54:57 EST
Yes, *.profile.uml contains everything - except libraries, but they should have their own *.genmodel as well. I wasn't aware of that.

However, if we also consider performances, one of the issues in the current state is that once we have access to the *.profile.uml, we still need to inspect it to find the sub-profiles, which may take some time (To take the SysML 1.4 mentioned above, just registering each sub-profile individually sped up execution time several times; and the root profile was already correctly registered. But then I'm not sure if we could simply have optimized the lookup for nested profiles, instead of registering each of them individually).

Still, I guess that's one approach to consider. We may even do that while initializing the UML Registry, to do it only once (i.e. derive all the information currently defined in the extension points, on startup). Although it would increase startup time, so I'm not sure we want that.
Comment 11 Ed Willink CLA 2018-01-18 11:03:25 EST
IMHO the major contribution of the UML2 project compared to a naive genmodel of UML.ecore is its pragmatic caches.

I suggest identifying what is inadequately cached and formulating a new lazy analyzer to populate these caches from existing information.
Comment 12 Ed Willink CLA 2018-01-18 11:07:36 EST
(In reply to Ed Willink from comment #11)
> I suggest identifying what is inadequately cached and formulating a new lazy
> analyzer to populate these caches from existing information.

If this information is expensive to compute, it might be appropriate to cache it at GenModel-time in eAnnotations.
Comment 13 Kenn Hussey CLA 2018-01-18 15:02:32 EST
The extension point in UML2 was originally added for quick look-up of "dynamic" profiles (which have no associated generator model). It was later re-purposed for also looking up "static" profiles (which do have an associated generator model). I think it makes good sense to retain this extension point and expand its coverage to include packages because:

- generator models are development-time artifacts and there's go guarantee that they'll be both registered via the EMF extension point and available at runtime
- it's not valid to assume that all registered generator models are intended for use in this way with UML; indeed, we wouldn't want to go loading all available generator models looking for ones that happen to have been produced from a "foreign" UML model
Comment 14 Kenn Hussey CLA 2018-01-18 15:55:21 EST
(In reply to comment #8)
> Thanks, Camille, I'll take a look as soon as I am able.

I added some comment and requested that the contribution be re-based against the 'master' branch.
Comment 15 Eclipse Genie CLA 2018-01-19 02:57:34 EST
New Gerrit change created: https://git.eclipse.org/r/115672
Comment 16 Kenn Hussey CLA 2018-01-19 14:25:29 EST
(In reply to comment #15)
> New Gerrit change created: https://git.eclipse.org/r/115672

Thanks, I replied with comments (hopefully they came through).
Comment 18 Kenn Hussey CLA 2018-01-22 11:36:11 EST
The changes have been commited/pushed to the 'master' branch in git and will be available in the next integration build.
Comment 19 Kenn Hussey CLA 2018-01-22 14:30:35 EST
I had to (just now) reverse delegation for the protected hook method in the stereotype application helper in the interest of backwards compatibility. The original hook method was being completely bypassed by the logic, which would spell trouble for subclasses that may have overridden it. Luckily, there was a test that happen to catch this.
Comment 20 Kenn Hussey CLA 2018-01-22 17:00:18 EST
After thinking about it for a while, I realized that it made little sense to pass a stereotype argument to setBaseElement(...) only to check whether it was null (but do nothing with it). So I refactored the new version of it into a "basic" version that takes an Ecore class as an argument instead of the stereotype. This is the version that is now called from the stereotype application helper.

As for the stereotype application helper, I overloaded the removal method with a stereotype parameter as well and made the older versions (without the stereotype parameter) deprecated to indicate that the newer ones are preferred (in case there are opportunities to optimize performance based on knowing the stereotype).

I'll take a pass through references to the deprecated methods in the UML2 codebase now and update them to use the newer versions.
Comment 21 Kenn Hussey CLA 2018-01-22 20:36:18 EST
An integration build containing the changes is now available.
Comment 22 Toni Siljamäki CLA 2018-06-26 16:18:51 EDT
Hello Camille (and others), long time no see.

I have also seen the other Bug 530156 you have worked on, also dealing with DSL/Stereotype performance issues.

I have just created a new demonstrator DSML in Papyrus for the vehicle industry, partly like the NWADSL, but this one contains three integrated DSML's and their profiles for platform topology-, domain architecture- and system + function modeling, done in different but integrated models. (all based on a HW topology)

Each model element has 1-2 stereotypes applied (sometimes 3) with appropriate CSS customizations of the diagrams, of course :) , some also having one of many possible and additional stereotype applications stored in separate files.

The size (number of rules) in my several and quite large CSS stylesheets do not seem to be any problem whatsoever regarding performance, but model size does. (I have tested and verified it, I do not believe CSS has any significant performance issues, compared to stereotype applications)

But stereotyped model size is an issue. (compared to a model without stereotypes)

In my quite larger domain architecture model (377 stereotype applications in one model in one diagram) it seems that I suddenly hit some performance knee (some time ago) in Eclipse Papyrus or in UML2 or their combination.

Adding new elements in this model is quite slow, takes many seconds, and it takes 10sec just to open the model, so I suspect the stereotype applications to be the performance problem.

NOTE: I am using Neon.2, since this is the last version where I still could create customized DSML palettes, like we did (in the same way as) for the NWADSL.

QUESTION:

The solution for this stereotype performance bug and the Bug 530156 solved for Photon M7, do you think they will result in a significant performance increase in Photon for my domain architecture model, compared to when using Neon.2 ???

Did these performance issues exist in UML2 also for Neon.2 , but are solved now ?

Regards/Toni
Comment 23 Toni Siljamäki CLA 2018-06-26 16:42:28 EDT
...and:

Does creating static DSML profiles perhaps improve some overall performance? :)

(don't understand why anyone otherwise would like to create static profiles)
(...or go through the trouble creating static versions of evolving profiles)

Regards/Toni
Comment 24 Camille Letavernier CLA 2018-06-27 03:16:22 EDT
Hi Toni,

> The solution for this stereotype performance bug and the Bug 530156 solved for Photon M7, do you think they will result in a significant performance increase in Photon for my domain architecture model, compared to when using Neon.2 ???
> 
> Did these performance issues exist in UML2 also for Neon.2 , but are solved now ?

This performance issue has been present for quite some time (I'd say around the Indigo/Juno release), but I'm not sure that it affects dynamic profiles.

> Does creating static DSML profiles perhaps improve some overall performance? :)

Not necessarily. Static profiles are useful if you want to manipulate the models in Java, but they don't bring too much benefits otherwise. Especially, as you said, if they evolve a lot. Dynamic profiles are easier to manipulate, and it's harder to make mistakes that will cause performance issues.

One thing that may cause performance issues with dynamic profile is a large history of profile definitions. Papyrus never cleans these up automatically, so it's a good idea to remove them manually when they are no longer required (Note however that version history is used for automatic model migration, so usually you want to preserve at least the release versions of the profile, and maybe just remove the nightlies).

Each definition is pretty much a copy (snapshot) of the original profile, so they can accumulate quite quickly, and make the model that much more expensive to load & manipulate.
Comment 25 Toni Siljamäki CLA 2018-06-27 17:08:29 EDT
Created attachment 274651 [details]
Domain Architecture screenshot

Thanks Camille. (wish you luck in the football championship :) sweden just made it to the quarter finals :) and luck to you in your new job :) )

It sounds promising that these UML2 performance issues are so very old, and that some of them are perhaps solved now in Photon... (scaling-up testing is always a good thing)
Photon GA should be available today btw, but I cannot find it, and not the earlier RC4 release either...

NOTE: Before my performance testing I made sure to delete all the latest 20+ history versions of these 3 new DSML profiles, mainly for memory cost reasons (and garbage deletion), but after I updated all models+profiles to the latest DSML profile versions.

I did some additional performance testing today, and this scaling-up-issue / performance-knee seem to only have to do with opening larger diagrams = many elements with stereotypes applied.
Only you guys can tell if this CPU load cost for opening diagrams is lost in (related to) low-performing UML2 API's...

Attached is an obfuscated screenshot of the top-level Domain Architecture model/diagram I'm testing for this new DSML. (having 377 stereotype applications in its elements)

Here are the test results from today:

* Open original model+diagram using DSML: 9 sec
* Open again, stereotype applications removed: 3.5 sec
* Open again, no sterotype apps & without CSS rules in DSML: 3.5 sec
* Open original model without CSS rules in DSML: 7 sec

* Open original model but not its diagram: 0.5 sec
* ...then open the diagram: 8 sec
* ...then close the diagram and open it again: 3 sec

* Open the original model+diagram after starting Eclipse/Papyrus: 20 sec

In these tests I have been using the most powerful ASUS gaming machine (laptop), because I like to have short turnaround times when developing new DSML plugins for Papyrus. :)

Could anyone please check if there are any other low-performing UML2 API's involved in the opening of diagrams in Papyrus ???
(related to model elements and/or stereotype applications)

Earlier we solved some significant Papyrus performance issues via profiling, when using larger models and diagrams. :)
Regards/Toni
Comment 26 Camille Letavernier CLA 2018-06-28 03:51:30 EDT
You can download Photon here: http://www.eclipse.org/photon/ (Via the Eclipse Installer), or here: https://www.eclipse.org/downloads/eclipse-packages/ (To directly download some packages)

I think it's best if you test it yourself, and open a new ticket on Papyrus if you still get some significant performance issues

The patch provided in this ticket was (IIRC) developed for static profiles, because all the profiles in Papyrus are static (They are standard, so they don't evolve too much, and it's easier to develop tooling based on the generated java code), but it might also help with dynamic profiles (or maybe not)
Comment 27 Kenn Hussey CLA 2018-06-28 11:38:40 EDT
The changes are available in UML2 5.4.0 (as part of the simultaneous Eclipse Photon release).