1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
/********************************************************************
* Copyright (c) 2008 Contributors. All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* Andy Clement initial implementation
*******************************************************************/
package org.aspectj.systemtest.incremental.tools;
import java.io.IOException;
import org.aspectj.ajde.core.ICompilerConfiguration;
/**
* Testing the performance of incremental compilation as it would be in AJDT.
*
* @author AndyClement
*/
public class IncrementalPerformanceTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed {
/**
* Build a project of 64 source files and no aspects.<br>
* <ul>
* <li>First build is a full build.
* <li>Second build is an incremental build with no changes at all.
* <li>Third build is an incremental build with just a source file touched (not changed).
* </ul>
*
* <p>
* 162-dev, 28Aug08 times: Thinkpad T61p: 3203/3140/3234/3156 173/172/172/172 313/297/297/312
*/
public void testBuildingProject64Files() {
String proj = "Proj64";
// A full build:
initialiseProject(proj);
build(proj);
checkWasFullBuild();
long fullbuildtime = getTimeTakenForBuild(proj);
System.out.println("Full build time: " + fullbuildtime + "ms");
// An incremental build with no source file changes at all. What should happen?
// We need to determine that nothing has to be done as fast as possible, this is all about
// determining from the configuration that nothing has changed and returning as fast as possible. Any
// delays here are unnecessary burden that will hurt every other kind of compilation.
build(proj);
checkWasntFullBuild();
checkCompileWeaveCount(proj, 0, 0);
long nochangebuild = getTimeTakenForBuild(proj);
System.out.println("Incr build time for no changes at all: " + nochangebuild + "ms");
// An incremental build with no source file changes at all *and* we tell the compiler there are
// no source changes (so it doesn't need to check timestamps). super fast
addProjectSourceFileChanged(proj, null);
build(proj);
checkWasntFullBuild();
checkCompileWeaveCount(proj, 0, 0);
long nochangebuildandDoTellCompiler = getTimeTakenForBuild(proj);
System.out.println("Incr build time for no changes at all and telling the compiler that: " + nochangebuildandDoTellCompiler
+ "ms");
// Now we touch a file (C0.java) and call build. What should happen?
// We need to determine what has changed, we'll do that by walking over the set of input files and
// checking their last modified stamps. So although we won't rebuild a buildConfig object, we will
// call lastModifiedTime() a lot to determine which file has changed.
alter(proj, "inc1");
build(proj);
checkWasntFullBuild();
checkCompileWeaveCount(proj, 1, 1);
long whitespacechangeDontTellCompiler = getTimeTakenForBuild(proj);
System.out.println("Incr build time for whitespace change: " + whitespacechangeDontTellCompiler + "ms");
// Similar to previous test, touch that file, but this time tell the compiler which file has changed. What should happen?
// As we are telling the compiler what has changed, it will not jump through hoops checking the last mod time of
// every source file in the project configuration.
alter(proj, "inc1");
addProjectSourceFileChanged(proj, getProjectRelativePath(proj, "src/out/C0.java"));
build(proj);
checkWasntFullBuild();
checkCompileWeaveCount(proj, 1, 1);
long whitespacechangeDoTellCompiler = getTimeTakenForBuild(proj);
System.out.println("Incr build time for whitespace change (where we tell the compiler what changed): "
+ whitespacechangeDoTellCompiler + "ms");
// Lets assert what really ought to be true
assertTrue(nochangebuild < fullbuildtime);
assertTrue(whitespacechangeDontTellCompiler < fullbuildtime);
assertTrue(whitespacechangeDoTellCompiler < fullbuildtime);
assertTrue(nochangebuild < whitespacechangeDontTellCompiler);
// assertTrue(nochangebuild < whitespacechangeDoTellCompiler);
// assertTrue(whitespacechangeDoTellCompiler < whitespacechangeDontTellCompiler);
}
/**
* Project dependencies are captured by using classpath. The dependee project has the bin folder for the project upon which it
* depends on its classpath. This can make it expensive when determining whether to build the dependee project as we may need to
* analyse all the classpath entries, we don't know which are project related. However, a new API in ICompilerConfiguration
* called getClasspathElementsWithModifiedContents() can be returned by an implementor to tell us which parts of the classpath
* to check.
*/
public void testBuildingTwoProjects() {
String projA = "Proj64";
String projB = "Dependee";
// A full build:
initialiseProject(projA);
initialiseProject(projB);
configureNewProjectDependency(projB, projA);
build(projA);
checkWasFullBuild();
build(projB);
checkWasFullBuild();
alter(projA, "C43changeOne"); // C43 made package private
build(projA);
setNextChangeResponse(projB, ICompilerConfiguration.EVERYTHING);
build(projB);
long timeTakenWhenFullyAnalysingClasspath = getTimeTakenForBuild(projB);
checkWasntFullBuild();
alter(projA, "C43changeOne"); // C43 made package private
build(projA);
addClasspathEntryChanged(projB, getProjectRelativePath(projA, "bin").getPath());
// waitForReturn();
build(projB);
long timeTakenWhenFullyToldSpecifically = getTimeTakenForBuild(projB);
// waitFor10();
checkWasntFullBuild();
System.out.println("Without: " + timeTakenWhenFullyAnalysingClasspath + "ms With: " + timeTakenWhenFullyToldSpecifically
+ "ms");
}
// --- helper code ---
@SuppressWarnings("unused")
private void waitFor10() {
try {
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unused")
private void waitForReturn() {
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
testdataSrcDir = "../tests/incrementalPerformance";
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
testdataSrcDir = "../tests/multiIncremental";
}
}
|