Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 501740 | Differences between
and this patch

Collapse All | Expand All

(-)a/plugins/org.eclipse.uml2.uml/src/org/eclipse/uml2/uml/util/UMLUtil.java (-8 / +16 lines)
Lines 14-20 Link Here
14
 *   Yann Tanguy (CEA) - 350402
14
 *   Yann Tanguy (CEA) - 350402
15
 *   Christian W. Damus (CEA) - 392833, 251963, 405061, 409396, 176998, 180744, 403374, 416833, 420338, 405065, 431342
15
 *   Christian W. Damus (CEA) - 392833, 251963, 405061, 409396, 176998, 180744, 403374, 416833, 420338, 405065, 431342
16
 *   E.D.Willink - 420338
16
 *   E.D.Willink - 420338
17
 *   Christian W. Damus - 444588, 497359
17
 *   Christian W. Damus - 444588, 497359, 501740
18
 *
18
 *
19
 */
19
 */
20
package org.eclipse.uml2.uml.util;
20
package org.eclipse.uml2.uml.util;
Lines 11880-11896 Link Here
11880
		private static final OperationContext NULL = new OperationContext() {
11880
		private static final OperationContext NULL = new OperationContext() {
11881
			@Override
11881
			@Override
11882
			NamedElement getTarget(ENamedElement definition) {
11882
			NamedElement getTarget(ENamedElement definition) {
11883
				return null;
11883
				NamedElement result = null;
11884
			}
11884
				@SuppressWarnings("unchecked")
11885
11885
				Map<ENamedElement, NamedElement> cache = (Map<ENamedElement, NamedElement>)CacheAdapter.getInstance().get(null, this);
11886
			@Override
11886
				if (cache != null) {
11887
			NamedElement getNamedElement(ENamedElement definition, EObject context) {
11887
					result = cache.get(definition);
11888
				return UMLUtil.basicGetNamedElement(definition, context);
11888
				}
11889
				return result;
11889
			}
11890
			}
11890
11891
11891
			@Override
11892
			@Override
11892
			void cacheNamedElement(ENamedElement definition, NamedElement target) {
11893
			void cacheNamedElement(ENamedElement definition, NamedElement target) {
11893
				// Pass
11894
				CacheAdapter adapter = CacheAdapter.getInstance();
11895
				@SuppressWarnings("unchecked")
11896
				Map<ENamedElement, NamedElement> cache = (Map<ENamedElement, NamedElement>)adapter.get(null, this);
11897
				if (cache == null) {
11898
					cache = new HashMap<ENamedElement, NamedElement>();
11899
					adapter.put(null, this, cache);
11900
				}
11901
				cache.put(definition, target);
11894
			}
11902
			}
11895
		};
11903
		};
11896
11904
(-)a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug497359Test.java (-13 lines)
Lines 79-97 Link Here
79
		});
79
		});
80
	}
80
	}
81
81
82
	/**
83
	 * Verify that even just accessing stereotype applications is improved
84
	 * within in a profile operation context.
85
	 */
86
	public void testGetStereotypeApplications() {
87
		runProfileOperationExperiment("get stereotypes", 9, new Runnable() {
88
			
89
			public void run() {
90
				walkAllStereotypeApplications(fixture);
91
			}
92
		});
93
	}
94
95
	//
82
	//
96
	// Test framework
83
	// Test framework
97
	//
84
	//
(-)a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/Bug501740Test.java (+196 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2016 Christian W. Damus and others.
3
 * 
4
 * All rights reserved. This program and the accompanying materials
5
 * are made available under the terms of the Eclipse Public License v1.0
6
 * which accompanies this distribution, and is available at
7
 * http://www.eclipse.org/legal/epl-v10.html
8
 *
9
 * Contributors:
10
 *   Christian W. Damus - initial API and implementation
11
 *
12
 */
13
package org.eclipse.uml2.uml.bug.tests;
14
15
import java.util.List;
16
17
import org.eclipse.emf.common.util.URI;
18
import org.eclipse.emf.ecore.EClass;
19
import org.eclipse.emf.ecore.EObject;
20
import org.eclipse.emf.ecore.resource.Resource;
21
import org.eclipse.emf.ecore.resource.ResourceSet;
22
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
23
import org.eclipse.uml2.common.util.CacheAdapter;
24
import org.eclipse.uml2.common.util.UML2Util;
25
import org.eclipse.uml2.uml.Artifact;
26
import org.eclipse.uml2.uml.Class;
27
import org.eclipse.uml2.uml.Element;
28
import org.eclipse.uml2.uml.Package;
29
import org.eclipse.uml2.uml.PackageableElement;
30
import org.eclipse.uml2.uml.Profile;
31
import org.eclipse.uml2.uml.Stereotype;
32
import org.eclipse.uml2.uml.UMLFactory;
33
import org.eclipse.uml2.uml.UMLPackage;
34
import org.eclipse.uml2.uml.profile.standard.StandardPackage;
35
import org.eclipse.uml2.uml.resource.UMLResource;
36
import org.eclipse.uml2.uml.tests.util.StandaloneSupport;
37
import org.eclipse.uml2.uml.tests.util.Stopwatch;
38
import org.eclipse.uml2.uml.util.UMLUtil.StereotypeApplicationHelper;
39
40
import junit.framework.Test;
41
import junit.framework.TestCase;
42
import junit.framework.TestSuite;
43
44
/**
45
 * Tests the performance of operations on stereotype applications from static
46
 * profiles.
47
 * 
48
 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=501740
49
 */
50
public class Bug501740Test
51
		extends TestCase {
52
53
	private static final int ITERATIONS = 10;
54
55
	private ResourceSet rset;
56
57
	private Package fixture;
58
59
	public Bug501740Test() {
60
		super();
61
	}
62
63
	public Bug501740Test(String name) {
64
		super(name);
65
	}
66
67
	public static Test suite() {
68
		return new TestSuite(Bug501740Test.class, "Bug 501740 tests"); //$NON-NLS-1$
69
	}
70
71
	public void testCreatingManyStereotypedElements() {
72
		Stopwatch watch = new Stopwatch();
73
74
		for (int i = 0; i < ITERATIONS; i++) {
75
			watch.start();
76
			createManyStereotypedElements();
77
			watch.end();
78
79
			// Clean up
80
			nextIteration();
81
		}
82
83
		watch.log("Creation");
84
	}
85
86
	private void createManyStereotypedElements() {
87
		for (int i = 0; i < 500; i++) {
88
			Class class_ = fixture.createOwnedClass(null, false);
89
			applyStereotype(class_, StandardPackage.Literals.AUXILIARY);
90
91
			Artifact artifact = (Artifact) fixture.createPackagedElement(null,
92
				UMLPackage.Literals.ARTIFACT);
93
			applyStereotype(artifact, StandardPackage.Literals.EXECUTABLE);
94
95
			Package nested = fixture.createNestedPackage(null);
96
			applyStereotype(nested, StandardPackage.Literals.MODEL_LIBRARY);
97
		}
98
	}
99
100
	public void testReadingManyStereotypedElements() {
101
		Stopwatch watch = new Stopwatch();
102
103
		// Create a bunch of elements to read
104
		createManyStereotypedElements();
105
106
		for (int i = 0; i < ITERATIONS; i++) {
107
			watch.start();
108
			readManyStereotypedElements();
109
			watch.end();
110
111
			// Clean up
112
			CacheAdapter.getCacheAdapter(fixture).clear();
113
		}
114
115
		watch.log("Reading");
116
	}
117
118
	private void readManyStereotypedElements() {
119
		for (PackageableElement next : fixture.getPackagedElements()) {
120
			List<Stereotype> stereos = next.getAppliedStereotypes();
121
			assertTrue(stereos.size() == 1);
122
			assertEquals("StandardProfile",
123
				stereos.get(0).getProfile().getName());
124
		}
125
	}
126
127
	//
128
	// Test framework
129
	//
130
131
	@Override
132
	protected void setUp()
133
			throws Exception {
134
135
		rset = new ResourceSetImpl();
136
		if (StandaloneSupport.isStandalone()) {
137
			StandaloneSupport.init(rset);
138
		}
139
140
		fixture = getTestModel();
141
	}
142
143
	@Override
144
	protected void tearDown()
145
			throws Exception {
146
147
		fixture = null;
148
149
		// clean up the CacheAdapter as well as we can
150
		for (Resource next : rset.getResources()) {
151
			next.unload();
152
			next.eAdapters().clear();
153
		}
154
155
		rset.getResources().clear();
156
		rset.eAdapters().clear();
157
	}
158
159
	void nextIteration() {
160
		try {
161
			tearDown();
162
			setUp();
163
		} catch (Exception e) {
164
			e.printStackTrace();
165
			fail("Failed to reset for next iteration: " + e.getMessage());
166
		}
167
	}
168
169
	Package getTestModel() {
170
		// Just create a small model locally
171
		Resource resource = UMLResource.Factory.INSTANCE
172
			.createResource(URI.createURI("test:bug501740"));
173
		Package result = UMLFactory.eINSTANCE.createPackage();
174
		result.setName("bug501740");
175
		resource.getContents().add(result);
176
		rset.getResources().add(resource);
177
178
		// Apply the standard profile, which is statically generated
179
		Profile std = UML2Util.load(rset,
180
			URI.createURI(UMLResource.STANDARD_PROFILE_URI),
181
			UMLPackage.Literals.PROFILE);
182
		result.applyProfile(std);
183
184
		// Apply a stereotype to the package
185
		applyStereotype(result, StandardPackage.Literals.MODEL_LIBRARY);
186
187
		return result;
188
	}
189
190
	protected static EObject applyStereotype(Element element,
191
			EClass definition) {
192
		return StereotypeApplicationHelper.getInstance(element)
193
			.applyStereotype(element, definition);
194
	}
195
196
}
(-)a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/bug/tests/UMLBugTests.java (-1 / +2 lines)
Lines 10-16 Link Here
10
 *   Christian W. Damus (CEA) - 409396, 403365, 300957, 405061, 401682, 176998, 180744, 403374, 420338, 405065, 332057, 431342, 433149, 437977
10
 *   Christian W. Damus (CEA) - 409396, 403365, 300957, 405061, 401682, 176998, 180744, 403374, 420338, 405065, 332057, 431342, 433149, 437977
11
 *   Manuel Bork <bork@yatta.de> (Yatta Solutions GmbH) - 421756, 422000
11
 *   Manuel Bork <bork@yatta.de> (Yatta Solutions GmbH) - 421756, 422000
12
 *   Kenn Hussey (CEA) - 424895
12
 *   Kenn Hussey (CEA) - 424895
13
 *   Christian W. Damus - 444588, 497359
13
 *   Christian W. Damus - 444588, 497359, 501740
14
 *   
14
 *   
15
 */
15
 */
16
package org.eclipse.uml2.uml.bug.tests;
16
package org.eclipse.uml2.uml.bug.tests;
Lines 63-68 Link Here
63
		result.addTest(Bug444588StereotypesTest.suite());
63
		result.addTest(Bug444588StereotypesTest.suite());
64
		result.addTest(Bug444588ProfilesTest.suite());
64
		result.addTest(Bug444588ProfilesTest.suite());
65
		result.addTest(Bug497359Test.suite());
65
		result.addTest(Bug497359Test.suite());
66
		result.addTest(Bug501740Test.suite());
66
		
67
		
67
		// keep this one at the end because it runs long
68
		// keep this one at the end because it runs long
68
		result.addTest(Bug332057Test.suite());
69
		result.addTest(Bug332057Test.suite());
(-)a/tests/org.eclipse.uml2.uml.tests/src/org/eclipse/uml2/uml/tests/util/Stopwatch.java (+173 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2016 Christian W. Damus and others.
3
 * All rights reserved.   This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *   Christian W. Damus - initial API and implementation
10
 *
11
 */
12
package org.eclipse.uml2.uml.tests.util;
13
14
/**
15
 * A convenience for timing of executions in tests.
16
 */
17
public class Stopwatch {
18
19
	// The size of a sample large enough to exclude outliers
20
	private static final int LARGE_SAMPLE = 10;
21
22
	private long startMillis;
23
24
	private long[] samples;
25
26
	private int iterations;
27
28
	private int minSampleIdx;
29
30
	private int maxSampleIdx;
31
32
	private double averageMillis;
33
34
	private double stdevMillis;
35
36
	public Stopwatch() {
37
		super();
38
	}
39
40
	/**
41
	 * Reset all statistics.
42
	 */
43
	public void reset() {
44
		startMillis = 0L;
45
		iterations = 0;
46
		averageMillis = 0.0;
47
		stdevMillis = 0.0;
48
		samples = null;
49
		minSampleIdx = 0;
50
		maxSampleIdx = 0;
51
	}
52
53
	/**
54
	 * Start timing an iteration.
55
	 */
56
	public void start() {
57
		startMillis = System.currentTimeMillis();
58
	}
59
60
	/**
61
	 * Finish timing an iteration and recompute statistics.
62
	 */
63
	public void end() {
64
		long endMillis = System.currentTimeMillis();
65
66
		// Record the new sample
67
		int index = iterations;
68
		iterations = index + 1;
69
		long sample = endMillis - startMillis;
70
		samples = grow(samples, iterations);
71
		samples[iterations - 1] = sample;
72
73
		// Recompute stats
74
75
		if (samples[index] < samples[minSampleIdx]) {
76
			minSampleIdx = index;
77
		}
78
		if (samples[index] > samples[maxSampleIdx]) {
79
			maxSampleIdx = index;
80
		}
81
		averageMillis = sample;
82
		stdevMillis = 0.0;
83
84
		if (iterations > 1) {
85
			// We have some stats to compute
86
			double sum = 0.0;
87
88
			// If we have more than a few samples, then we toss
89
			// the high and low outliers
90
			int sampleSize = sampleSize();
91
92
			// Compute the sum of samples
93
			for (int i = 0; i < iterations; i++) {
94
				if (!isOutlier(i)) {
95
					sum = sum + samples[i];
96
				}
97
			}
98
99
			averageMillis = sum / sampleSize;
100
101
			// And a standard deviation
102
			double sumDevSq = 0.0;
103
			for (int i = 0; i < iterations; i++) {
104
				if (!isOutlier(i)) {
105
					double dev = samples[i] - averageMillis;
106
					sumDevSq = sumDevSq + (dev * dev);
107
				}
108
			}
109
			stdevMillis = Math.sqrt(sumDevSq / (sampleSize - 1));
110
		}
111
	}
112
113
	private int sampleSize() {
114
		return (iterations >= LARGE_SAMPLE)
115
			? iterations - 2
116
			: iterations;
117
	}
118
119
	private boolean isOutlier(int sampleIndex) {
120
		return (iterations >= LARGE_SAMPLE)
121
			&& ((sampleIndex == minSampleIdx) || (sampleIndex == maxSampleIdx));
122
	}
123
124
	/**
125
	 * How many iterations have we timed?
126
	 * 
127
	 * @return the number of iterations
128
	 */
129
	public int iterations() {
130
		return iterations;
131
	}
132
133
	/**
134
	 * What is the average timing of an iteration?
135
	 * 
136
	 * @return the average iteration
137
	 */
138
	public double averageMillis() {
139
		return averageMillis;
140
	}
141
142
	/**
143
	 * What is the sample standard deviation of the timings of all iterations?
144
	 * 
145
	 * @return the iteration sample standard deviation
146
	 */
147
	public double stdevMillis() {
148
		return stdevMillis;
149
	}
150
151
	public void log(String message) {
152
		if (message != null) {
153
			System.out.printf("%s: ", message);
154
		}
155
		System.out.printf("%3.2f ms (σ = %01.3f ms) on %d iterations%n",
156
			averageMillis(), stdevMillis(), iterations());
157
	}
158
159
	private long[] grow(long[] array, int minCapacity) {
160
		long[] result;
161
162
		if (array == null) {
163
			result = new long[Math.max(minCapacity, 10)];
164
		} else if (array.length >= minCapacity) {
165
			result = array;
166
		} else {
167
			result = new long[Math.max(minCapacity, 10) * 5 / 3];
168
			System.arraycopy(array, 0, result, 0, array.length);
169
		}
170
171
		return result;
172
	}
173
}

Return to bug 501740