Skip to content

Commit 83b3619

Browse files
authored
Merge pull request #45 from retronym/topic/comparative-java
Add a comparative Java vs Scala benchmark
2 parents eec0a5a + 0040b1b commit 83b3619

38 files changed

+14523
-12
lines changed

LICENSE

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,70 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9999
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
100100
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
101101
SOFTWARE.
102+
103+
104+
105+
* RE2/J
106+
107+
This is a work derived from Russ Cox's RE2 in Go, whose license
108+
http://golang.org/LICENSE is as follows:
109+
110+
Copyright (c) 2009 The Go Authors. All rights reserved.
111+
112+
Redistribution and use in source and binary forms, with or without
113+
modification, are permitted provided that the following conditions are
114+
met:
115+
116+
* Redistributions of source code must retain the above copyright
117+
notice, this list of conditions and the following disclaimer.
118+
119+
* Redistributions in binary form must reproduce the above copyright
120+
notice, this list of conditions and the following disclaimer in
121+
the documentation and/or other materials provided with the
122+
distribution.
123+
124+
* Neither the name of Google Inc. nor the names of its contributors
125+
may be used to endorse or promote products derived from this
126+
software without specific prior written permission.
127+
128+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
129+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
130+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
131+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
132+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
133+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
134+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
135+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
136+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
137+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
138+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
139+
140+
* re2s (part of Scala Native)
141+
142+
Copyright (c) 2015-2017 EPFL
143+
144+
All rights reserved.
145+
146+
Redistribution and use in source and binary forms, with or without modification,
147+
are permitted provided that the following conditions are met:
148+
149+
* Redistributions of source code must retain the above copyright notice,
150+
this list of conditions and the following disclaimer.
151+
* Redistributions in binary form must reproduce the above copyright notice,
152+
this list of conditions and the following disclaimer in the documentation
153+
and/or other materials provided with the distribution.
154+
* Neither the name of the EPFL nor the names of its contributors
155+
may be used to endorse or promote products derived from this software
156+
without specific prior written permission.
157+
158+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
159+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
160+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
161+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
162+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
163+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
164+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
165+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
166+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
167+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
168+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,104 @@
11
package scala.tools.nsc;
22

3+
import org.openjdk.jmh.annotations.*;
4+
5+
import javax.tools.JavaCompiler;
6+
import javax.tools.ToolProvider;
7+
import java.io.File;
38
import java.io.IOException;
49
import java.nio.charset.Charset;
10+
import java.nio.file.FileVisitOption;
511
import java.nio.file.Files;
612
import java.nio.file.Path;
7-
import javax.tools.JavaCompiler;
8-
import javax.tools.ToolProvider;
13+
import java.nio.file.Paths;
14+
import java.util.ArrayList;
15+
import java.util.Collections;
16+
import java.util.List;
17+
import java.util.concurrent.TimeUnit;
18+
import java.util.stream.Collectors;
19+
import java.util.stream.Stream;
920

10-
import org.openjdk.jmh.annotations.Benchmark;
11-
import org.openjdk.jmh.annotations.Scope;
12-
import org.openjdk.jmh.annotations.Setup;
13-
import org.openjdk.jmh.annotations.State;
21+
import static org.openjdk.jmh.annotations.Mode.SampleTime;
1422

23+
@BenchmarkMode(SampleTime)
24+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
25+
@Warmup(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS)
26+
@Measurement(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS)
27+
@Fork(value = 3, jvmArgs = {"-Xms2G", "-Xmx2G"})
1528
@State(Scope.Thread)
1629
public class JavacBenchmark {
17-
// Prepare source somehow.
18-
String source = "public class Test { public Test() { System.out.println(\"world\"); } }";
30+
@Param(value = {})
31+
String source;
32+
33+
// This parameter is set by ScalacBenchmarkRunner / UploadingRunner based on the Scala version.
34+
// When running the benchmark directly the "latest" symlink is used.
35+
@Param(value = {"latest"})
36+
String corpusVersion;
37+
1938
private JavaCompiler compiler;
2039
private Path path;
2140

41+
private Path corpusSourcePath() {
42+
return Paths.get("..", "corpus", source, corpusVersion); };
43+
44+
private Path findSourceDir() {
45+
Path path = corpusSourcePath();
46+
return Files.exists(path) ? path : Paths.get(source);
47+
}
48+
49+
private List<String> sourceFiles() {
50+
if (source.startsWith("@")) return Collections.emptyList();
51+
else {
52+
List<Path> allFiles = walk(findSourceDir()).collect(Collectors.<Path>toList());
53+
return allFiles.stream().filter(f -> {
54+
String name = f.getFileName().toString();
55+
return name.endsWith(".scala") || name.endsWith(".java");
56+
}).map(x -> x.toAbsolutePath().normalize().toString()).collect(Collectors.toList());
57+
}
58+
}
59+
60+
private Stream<Path> walk(Path dir) {
61+
try {
62+
return Files.walk(dir, FileVisitOption.FOLLOW_LINKS);
63+
} catch (IOException e) {
64+
throw new RuntimeException(e);
65+
}
66+
}
67+
2268
@Setup
2369
public void setup() throws IOException {
24-
Path temp = Files.createTempDirectory("JavacBenchmark");
25-
path = temp.resolve("Test.java");
2670
compiler = ToolProvider.getSystemJavaCompiler();
27-
Files.write(path, source.getBytes(Charset.forName("UTF-8")));
2871
}
2972

3073
@Benchmark
3174
public int bench() {
3275
// Compile source file.
33-
int run = compiler.run(null, null, null, path.toAbsolutePath().toString());
76+
List<String> args = new ArrayList();
77+
args.add("-d");
78+
args.add(tempDir.getAbsolutePath());
79+
args.addAll(sourceFiles());
80+
int run = compiler.run(null, null, null, args.toArray(new String[]{}));
3481
assert run == 0;
3582
return run;
3683
}
84+
85+
86+
private File tempDir = null;
87+
88+
// Executed once per fork
89+
@Setup(Level.Trial) public void initTemp() {
90+
File tempFile = null;
91+
try {
92+
tempFile = File.createTempFile("output", "");
93+
} catch (IOException e) {
94+
throw new RuntimeException(e);
95+
}
96+
tempFile.delete();
97+
tempFile.mkdir();
98+
tempDir = tempFile;
99+
}
100+
@TearDown(Level.Trial) public void clearTemp() {
101+
BenchmarkUtils.deleteRecursive(tempDir.toPath());
102+
}
103+
37104
}

0 commit comments

Comments
 (0)