Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 264799 Details for
Bug 501740
Performance of UML definition look-up in static profiles
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
Updated patch for the master (Oxygen) branch
bug501740.patch (text/plain), 14.67 KB, created by
Christian Damus
on 2016-10-12 08:59:18 EDT
(
hide
)
Description:
Updated patch for the master (Oxygen) branch
Filename:
MIME Type:
Creator:
Christian Damus
Created:
2016-10-12 08:59:18 EDT
Size:
14.67 KB
patch
obsolete
>From cda51c5b02880260f269e5c31df1e157e67ded9d Wed, 12 Oct 2016 08:56:37 -0400 >From: Christian W. Damus <give.a.damus@gmail.com> >Date: Mon, 19 Sep 2016 09:56:12 -0400 >Subject: [PATCH] [501740] Performance of UML definition look-up in static profiles > > >Use the CacheAdapter to cache the results of look-up of UML definitions >for Ecore elements (especially in stereotypes) in the default (root) >OperationContext. > >diff --git a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java >index 06b555b..b833f34 100644 >--- a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java >+++ b/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java >@@ -14,7 +14,7 @@ > * Yann Tanguy (CEA) - 350402 > * Christian W. Damus (CEA) - 392833, 251963, 405061, 409396, 176998, 180744, 403374, 416833, 420338, 405065, 431342 > * E.D.Willink - 420338 >- * Christian W. Damus - 444588, 497359 >+ * Christian W. Damus - 444588, 497359, 501740 > * > */ > package org.eclipse.uml2.uml.util; >@@ -11873,32 +11873,41 @@ > private static class OperationContext { > > /** >- * The null context is the root and is always present, providing the >- * default behaviour of just always calculating the results required >- * by the client. >+ * The default context is the root and is always present, providing the >+ * default behaviour of calculating results and cacheing them in the >+ * {@link CacheAdapter}. Thus, the cache may be purged more agressively >+ * than is needed, but not often when simply inspecting a model. > */ >- private static final OperationContext NULL = new OperationContext() { >+ private static final OperationContext DEFAULT = new OperationContext() { > @Override > NamedElement getTarget(ENamedElement definition) { >- return null; >- } >- >- @Override >- NamedElement getNamedElement(ENamedElement definition, EObject context) { >- return UMLUtil.basicGetNamedElement(definition, context); >+ NamedElement result = null; >+ @SuppressWarnings("unchecked") >+ Map<ENamedElement, NamedElement> cache = (Map<ENamedElement, NamedElement>)CacheAdapter.getInstance().get(null, this); >+ if (cache != null) { >+ result = cache.get(definition); >+ } >+ return result; > } > > @Override > void cacheNamedElement(ENamedElement definition, NamedElement target) { >- // Pass >+ CacheAdapter adapter = CacheAdapter.getInstance(); >+ @SuppressWarnings("unchecked") >+ Map<ENamedElement, NamedElement> cache = (Map<ENamedElement, NamedElement>)adapter.get(null, this); >+ if (cache == null) { >+ cache = new HashMap<ENamedElement, NamedElement>(); >+ adapter.put(null, this, cache); >+ } >+ cache.put(definition, target); > } > }; > >- /** The current thread's active context (always at least the NULL). */ >+ /** The current thread's active context (always at least the {@link #DEFAULT}). */ > private static final ThreadLocal<OperationContext> context = new ThreadLocal<OperationContext>() { > @Override > protected OperationContext initialValue() { >- return NULL; >+ return DEFAULT; > } > }; > >diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug497359Test.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug497359Test.java >index 32e8096..b281e25 100644 >--- a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug497359Test.java >+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug497359Test.java >@@ -79,19 +79,6 @@ > }); > } > >- /** >- * Verify that even just accessing stereotype applications is improved >- * within in a profile operation context. >- */ >- public void testGetStereotypeApplications() { >- runProfileOperationExperiment("get stereotypes", 9, new Runnable() { >- >- public void run() { >- walkAllStereotypeApplications(fixture); >- } >- }); >- } >- > // > // Test framework > // >diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug501740Test.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug501740Test.java >new file mode 100644 >index 0000000..a901c83 >--- /dev/null >+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug501740Test.java >@@ -0,0 +1,196 @@ >+/* >+ * Copyright (c) 2016 Christian W. Damus and others. >+ * >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Christian W. Damus - initial API and implementation >+ * >+ */ >+package org.eclipse.uml2.uml.bug.tests; >+ >+import java.util.List; >+ >+import org.eclipse.emf.common.util.URI; >+import org.eclipse.emf.ecore.EClass; >+import org.eclipse.emf.ecore.EObject; >+import org.eclipse.emf.ecore.resource.Resource; >+import org.eclipse.emf.ecore.resource.ResourceSet; >+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; >+import org.eclipse.uml2.common.util.CacheAdapter; >+import org.eclipse.uml2.common.util.UML2Util; >+import org.eclipse.uml2.uml.Artifact; >+import org.eclipse.uml2.uml.Class; >+import org.eclipse.uml2.uml.Element; >+import org.eclipse.uml2.uml.Package; >+import org.eclipse.uml2.uml.PackageableElement; >+import org.eclipse.uml2.uml.Profile; >+import org.eclipse.uml2.uml.Stereotype; >+import org.eclipse.uml2.uml.UMLFactory; >+import org.eclipse.uml2.uml.UMLPackage; >+import org.eclipse.uml2.uml.profile.standard.StandardPackage; >+import org.eclipse.uml2.uml.resource.UMLResource; >+import org.eclipse.uml2.uml.tests.util.StandaloneSupport; >+import org.eclipse.uml2.uml.tests.util.Stopwatch; >+import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper; >+ >+import junit.framework.Test; >+import junit.framework.TestCase; >+import junit.framework.TestSuite; >+ >+/** >+ * Tests the performance of operations on stereotype applications from static >+ * profiles. >+ * >+ * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=501740 >+ */ >+public class Bug501740Test >+ extends TestCase { >+ >+ private static final int ITERATIONS = 10; >+ >+ private ResourceSet rset; >+ >+ private Package fixture; >+ >+ public Bug501740Test() { >+ super(); >+ } >+ >+ public Bug501740Test(String name) { >+ super(name); >+ } >+ >+ public static Test suite() { >+ return new TestSuite(Bug501740Test.class, "Bug 501740 tests"); //$NON-NLS-1$ >+ } >+ >+ public void testCreatingManyStereotypedElements() { >+ Stopwatch watch = new Stopwatch(); >+ >+ for (int i = 0; i < ITERATIONS; i++) { >+ watch.start(); >+ createManyStereotypedElements(); >+ watch.end(); >+ >+ // Clean up >+ nextIteration(); >+ } >+ >+ watch.log("Creation"); >+ } >+ >+ private void createManyStereotypedElements() { >+ for (int i = 0; i < 500; i++) { >+ Class class_ = fixture.createOwnedClass(null, false); >+ applyStereotype(class_, StandardPackage.Literals.AUXILIARY); >+ >+ Artifact artifact = (Artifact) fixture.createPackagedElement(null, >+ UMLPackage.Literals.ARTIFACT); >+ applyStereotype(artifact, StandardPackage.Literals.EXECUTABLE); >+ >+ Package nested = fixture.createNestedPackage(null); >+ applyStereotype(nested, StandardPackage.Literals.MODEL_LIBRARY); >+ } >+ } >+ >+ public void testReadingManyStereotypedElements() { >+ Stopwatch watch = new Stopwatch(); >+ >+ // Create a bunch of elements to read >+ createManyStereotypedElements(); >+ >+ for (int i = 0; i < ITERATIONS; i++) { >+ watch.start(); >+ readManyStereotypedElements(); >+ watch.end(); >+ >+ // Clean up >+ CacheAdapter.getCacheAdapter(fixture).clear(); >+ } >+ >+ watch.log("Reading"); >+ } >+ >+ private void readManyStereotypedElements() { >+ for (PackageableElement next : fixture.getPackagedElements()) { >+ List<Stereotype> stereos = next.getAppliedStereotypes(); >+ assertTrue(stereos.size() == 1); >+ assertEquals("StandardProfile", >+ stereos.get(0).getProfile().getName()); >+ } >+ } >+ >+ // >+ // Test framework >+ // >+ >+ @Override >+ protected void setUp() >+ throws Exception { >+ >+ rset = new ResourceSetImpl(); >+ if (StandaloneSupport.isStandalone()) { >+ StandaloneSupport.init(rset); >+ } >+ >+ fixture = getTestModel(); >+ } >+ >+ @Override >+ protected void tearDown() >+ throws Exception { >+ >+ fixture = null; >+ >+ // clean up the CacheAdapter as well as we can >+ for (Resource next : rset.getResources()) { >+ next.unload(); >+ next.eAdapters().clear(); >+ } >+ >+ rset.getResources().clear(); >+ rset.eAdapters().clear(); >+ } >+ >+ void nextIteration() { >+ try { >+ tearDown(); >+ setUp(); >+ } catch (Exception e) { >+ e.printStackTrace(); >+ fail("Failed to reset for next iteration: " + e.getMessage()); >+ } >+ } >+ >+ Package getTestModel() { >+ // Just create a small model locally >+ Resource resource = UMLResource.Factory.INSTANCE >+ .createResource(URI.createURI("test:bug501740")); >+ Package result = UMLFactory.eINSTANCE.createPackage(); >+ result.setName("bug501740"); >+ resource.getContents().add(result); >+ rset.getResources().add(resource); >+ >+ // Apply the standard profile, which is statically generated >+ Profile std = UML2Util.load(rset, >+ URI.createURI(UMLResource.STANDARD_PROFILE_URI), >+ UMLPackage.Literals.PROFILE); >+ result.applyProfile(std); >+ >+ // Apply a stereotype to the package >+ applyStereotype(result, StandardPackage.Literals.MODEL_LIBRARY); >+ >+ return result; >+ } >+ >+ protected static EObject applyStereotype(Element element, >+ EClass definition) { >+ return StereotypeApplicationHelper.getInstance(element) >+ .applyStereotype(element, definition); >+ } >+ >+} >diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java >index c96c4f8..a43d331 100644 >--- a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java >+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java >@@ -10,7 +10,7 @@ > * Christian W. Damus (CEA) - 409396, 403365, 300957, 405061, 401682, 176998, 180744, 403374, 420338, 405065, 332057, 431342, 433149, 437977 > * Manuel Bork <bork@yatta.de> (Yatta Solutions GmbH) - 421756, 422000 > * Kenn Hussey (CEA) - 424895 >- * Christian W. Damus - 444588, 497359 >+ * Christian W. Damus - 444588, 497359, 501740 > * > */ > package org.eclipse.uml2.uml.bug.tests; >@@ -63,6 +63,7 @@ > result.addTest(Bug444588StereotypesTest.suite()); > result.addTest(Bug444588ProfilesTest.suite()); > result.addTest(Bug497359Test.suite()); >+ result.addTest(Bug501740Test.suite()); > > // keep this one at the end because it runs long > result.addTest(Bug332057Test.suite()); >diff --git a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/tests/util/Stopwatch.java b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/tests/util/Stopwatch.java >new file mode 100644 >index 0000000..739d918 >--- /dev/null >+++ b/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/tests/util/Stopwatch.java >@@ -0,0 +1,173 @@ >+/* >+ * Copyright (c) 2016 Christian W. Damus and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * Christian W. Damus - initial API and implementation >+ * >+ */ >+package org.eclipse.uml2.uml.tests.util; >+ >+/** >+ * A convenience for timing of executions in tests. >+ */ >+public class Stopwatch { >+ >+ // The size of a sample large enough to exclude outliers >+ private static final int LARGE_SAMPLE = 10; >+ >+ private long startMillis; >+ >+ private long[] samples; >+ >+ private int iterations; >+ >+ private int minSampleIdx; >+ >+ private int maxSampleIdx; >+ >+ private double averageMillis; >+ >+ private double stdevMillis; >+ >+ public Stopwatch() { >+ super(); >+ } >+ >+ /** >+ * Reset all statistics. >+ */ >+ public void reset() { >+ startMillis = 0L; >+ iterations = 0; >+ averageMillis = 0.0; >+ stdevMillis = 0.0; >+ samples = null; >+ minSampleIdx = 0; >+ maxSampleIdx = 0; >+ } >+ >+ /** >+ * Start timing an iteration. >+ */ >+ public void start() { >+ startMillis = System.currentTimeMillis(); >+ } >+ >+ /** >+ * Finish timing an iteration and recompute statistics. >+ */ >+ public void end() { >+ long endMillis = System.currentTimeMillis(); >+ >+ // Record the new sample >+ int index = iterations; >+ iterations = index + 1; >+ long sample = endMillis - startMillis; >+ samples = grow(samples, iterations); >+ samples[iterations - 1] = sample; >+ >+ // Recompute stats >+ >+ if (samples[index] < samples[minSampleIdx]) { >+ minSampleIdx = index; >+ } >+ if (samples[index] > samples[maxSampleIdx]) { >+ maxSampleIdx = index; >+ } >+ averageMillis = sample; >+ stdevMillis = 0.0; >+ >+ if (iterations > 1) { >+ // We have some stats to compute >+ double sum = 0.0; >+ >+ // If we have more than a few samples, then we toss >+ // the high and low outliers >+ int sampleSize = sampleSize(); >+ >+ // Compute the sum of samples >+ for (int i = 0; i < iterations; i++) { >+ if (!isOutlier(i)) { >+ sum = sum + samples[i]; >+ } >+ } >+ >+ averageMillis = sum / sampleSize; >+ >+ // And a standard deviation >+ double sumDevSq = 0.0; >+ for (int i = 0; i < iterations; i++) { >+ if (!isOutlier(i)) { >+ double dev = samples[i] - averageMillis; >+ sumDevSq = sumDevSq + (dev * dev); >+ } >+ } >+ stdevMillis = Math.sqrt(sumDevSq / (sampleSize - 1)); >+ } >+ } >+ >+ private int sampleSize() { >+ return (iterations >= LARGE_SAMPLE) >+ ? iterations - 2 >+ : iterations; >+ } >+ >+ private boolean isOutlier(int sampleIndex) { >+ return (iterations >= LARGE_SAMPLE) >+ && ((sampleIndex == minSampleIdx) || (sampleIndex == maxSampleIdx)); >+ } >+ >+ /** >+ * How many iterations have we timed? >+ * >+ * @return the number of iterations >+ */ >+ public int iterations() { >+ return iterations; >+ } >+ >+ /** >+ * What is the average timing of an iteration? >+ * >+ * @return the average iteration >+ */ >+ public double averageMillis() { >+ return averageMillis; >+ } >+ >+ /** >+ * What is the sample standard deviation of the timings of all iterations? >+ * >+ * @return the iteration sample standard deviation >+ */ >+ public double stdevMillis() { >+ return stdevMillis; >+ } >+ >+ public void log(String message) { >+ if (message != null) { >+ System.out.printf("%s: ", message); >+ } >+ System.out.printf("%3.2f ms (Ï = %01.3f ms) on %d iterations%n", >+ averageMillis(), stdevMillis(), iterations()); >+ } >+ >+ private long[] grow(long[] array, int minCapacity) { >+ long[] result; >+ >+ if (array == null) { >+ result = new long[Math.max(minCapacity, 10)]; >+ } else if (array.length >= minCapacity) { >+ result = array; >+ } else { >+ result = new long[Math.max(minCapacity, 10) * 5 / 3]; >+ System.arraycopy(array, 0, result, 0, array.length); >+ } >+ >+ return result; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
Kenn.Hussey
:
review+
Actions:
View
|
Diff
Attachments on
bug 501740
:
264261
|
264262
| 264799