Skip to content

Commit 99574e2

Browse files
committed
Avoid unnecessary file IO when computing positions
The exists call introduced in #8883 and #8897 lead to a slowdown noticeable in benchmarks. Replace them by a check on the content length, since SourceFile caches its content this should avoid any unnecessary IO operation. This required changing the way SourceFile handles empty files to have it return an empty string instead of crashing.
1 parent e5e489e commit 99574e2

File tree

3 files changed

+17
-10
lines changed

3 files changed

+17
-10
lines changed

compiler/src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
5252

5353
def maybeIncomplete: Boolean = _maybeInComplete
5454

55-
def this(file: AbstractFile, codec: Codec) = this(file, new String(file.toByteArray, codec.charSet).toCharArray)
55+
def this(file: AbstractFile, codec: Codec) =
56+
// It would be cleaner to check if the file exists instead of catching
57+
// an exception, but it turns out that Files.exists is remarkably slow,
58+
// at least on Java 8 (https://rules.sonarsource.com/java/tag/performance/RSPEC-3725),
59+
// this is significant enough to show up in our benchmarks.
60+
this(file,
61+
try new String(file.toByteArray, codec.charSet).toCharArray
62+
catch case _: java.nio.file.NoSuchFileException => Array[Char]())
5663

5764
/** Tab increment; can be overridden */
5865
def tabInc: Int = 8

compiler/src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ extends interfaces.SourcePosition with Showable {
4242
def beforeAndAfterPoint: (List[Int], List[Int]) =
4343
lineOffsets.partition(_ <= point)
4444

45-
def column: Int = if (source.file.exists) source.column(point) else -1
45+
def column: Int = if (source.content().length != 0) source.column(point) else -1
4646

4747
def start: Int = span.start
48-
def startLine: Int = if (source.file.exists) source.offsetToLine(start) else -1
49-
def startColumn: Int = if (source.file.exists) source.column(start) else -1
48+
def startLine: Int = if (source.content().length != 0) source.offsetToLine(start) else -1
49+
def startColumn: Int = if (source.content().length != 0) source.column(start) else -1
5050
def startColumnPadding: String = source.startColumnPadding(start)
5151

5252
def end: Int = span.end
53-
def endLine: Int = if (source.file.exists) source.offsetToLine(end) else -1
54-
def endColumn: Int = if (source.file.exists) source.column(end) else -1
53+
def endLine: Int = if (source.content().length != 0) source.offsetToLine(end) else -1
54+
def endColumn: Int = if (source.content().length != 0) source.column(end) else -1
5555

5656
def withOuter(outer: SourcePosition): SourcePosition = SourcePosition(source, span, outer)
5757
def withSpan(range: Span) = SourcePosition(source, range, outer)

sbt-bridge/src/xsbt/DelegatingReporter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public Optional<java.io.File> sourceFile() {
9191
return Optional.ofNullable(src.file().file());
9292
}
9393
public Optional<Integer> line() {
94-
if (!src.file().exists())
94+
if (src.content().length == 0)
9595
return Optional.empty();
9696

9797
int line = pos.line() + 1;
@@ -101,7 +101,7 @@ public Optional<Integer> line() {
101101
return Optional.of(line);
102102
}
103103
public String lineContent() {
104-
if (!src.file().exists())
104+
if (src.content().length == 0)
105105
return "";
106106

107107
String line = pos.lineContent();
@@ -116,13 +116,13 @@ public Optional<Integer> offset() {
116116
return Optional.of(pos.point());
117117
}
118118
public Optional<Integer> pointer() {
119-
if (!src.file().exists())
119+
if (src.content().length == 0)
120120
return Optional.empty();
121121

122122
return Optional.of(pos.point() - src.startOfLine(pos.point()));
123123
}
124124
public Optional<String> pointerSpace() {
125-
if (!src.file().exists())
125+
if (src.content().length == 0)
126126
return Optional.empty();
127127

128128
String lineContent = this.lineContent();

0 commit comments

Comments
 (0)