eclipse-sirius / sirius-emf-json

JSON-based EMF Resource implementation - part of Eclipse Sirius
https://eclipse.dev/sirius/sirius-web.html
Eclipse Public License 2.0
5 stars 10 forks source link

PackageNotFoundException is instanciated a lot and quite costly #36

Closed pcdavid closed 1 month ago

pcdavid commented 1 month ago

In org.eclipse.sirius.emfjson.utils.GsonEObjectDeserializer.deserializeMultipleNonContainmentEReference (among others) we try to resolve the resource part of a reference URI as an EPackage using getPackageForURI(String uriString).

This works for the case where the reference URI is of the form e.g. http://www.eclipse.org/emf/2002/Ecore#//EBoolean, but will fail in most concrete cases where the reference URI will be something like 52317c1f-0516-48b4-bad4-15a3a07aebe9#//path/to/some/element.1. In such a case getPackageForURI keeps track of the error with:

this.helper.getResource().getErrors().add(new PackageNotFoundException(uriString, this.helper.getResourceURI().toString()));

Unfortunately, the error type used, PackageNotFoundException is an actual Java exception, which is very costly to create (because of fillStackTrace). I'm not sure why this Resource.Diagnostic (along with all the other JsonException subtypes) are exceptions, but just commenting out this line to avoid creating thousands of exceptions when loading a medium-sized model give a significant performance boost:

Before (master, emf-json 2.3.9/master):

After (commented this.helper.getResource().getErrors().add(new PackageNotFoundException()))

Simply commenting out the code is probably too much, but replacing an exception with a plain Resource.Diagnostic object should get us most of the gain (I need to confirm).

pcdavid commented 1 month ago

Here's a measure of the time just building the PacakgeNotFoundException instances when loading the "Sirius Web" Papaya example:

image

pcdavid commented 1 month ago

After switching to a plain class implementing EMF's Resource.Diagnostic directly, it's still invoked 20k times but but now accounts for ~1ms in total:

image

(I had to switch to YourKit's tracing mode, as in sampling mode it's not even measurable).