[flang][runtime] Tweak GetNextNonBlank() performance (#164521)

When skipping blanks during input from an ASCII file, scan the buffered
characters directly when possible rather than using the more general
path. This adds complexity, but shaves a few percent off the runtime of
a code that reads in millions of list-directed integers (best time over
multiple runs goes from 17.56 to 16.84 sec).
This commit is contained in:
Peter Klausler
2025-10-24 12:13:01 -07:00
committed by GitHub
parent a377b85634
commit 1df7f2baa9
2 changed files with 32 additions and 13 deletions

View File

@@ -73,7 +73,6 @@ struct ConnectionState : public ConnectionAttributes {
auto least{leftTabLimit.value_or(0)};
auto newPos{positionInRecord + n};
positionInRecord = newPos < least ? least : newPos;
;
}
RT_API_ATTRS void BeginRecord() {

View File

@@ -184,6 +184,18 @@ public:
}
connection_.HandleRelativePosition(bytes);
}
RT_API_ATTRS bool SkipBlanks() {
if (at_) {
const char *start{at_};
while (at_ < limit_ && (*at_ == ' ' || *at_ == '\t' || *at_ == '\n')) {
++at_;
}
connection_.HandleRelativePosition(at_ - start);
return true;
} else {
return false;
}
}
// Could there be a list-directed repetition count here?
RT_API_ATTRS bool MightBeRepetitionCount() const {
@@ -289,24 +301,32 @@ public:
// Skips spaces, advances records, and ignores NAMELIST comments
RT_API_ATTRS common::optional<char32_t> GetNextNonBlank(
std::size_t &byteCount, FastAsciiField *fastField = nullptr) {
auto ch{GetCurrentChar(byteCount, fastField)};
bool inNamelist{mutableModes().inNamelist};
if (fastField) {
while (fastField->SkipBlanks()) {
if (auto ch{fastField->Next()}) {
if (inNamelist && *ch == '!') {
// skip namelist comment
} else {
byteCount = 1;
return ch;
}
}
if (!AdvanceRecord()) {
break;
}
fastField->NextRecord(*this);
}
}
auto ch{GetCurrentCharSlow(byteCount)};
while (!ch || *ch == ' ' || *ch == '\t' || *ch == '\n' ||
(inNamelist && *ch == '!')) {
if (ch && (*ch == ' ' || *ch == '\t' || *ch == '\n')) {
if (fastField) {
fastField->Advance(0, byteCount);
} else {
HandleRelativePosition(byteCount);
}
} else if (AdvanceRecord()) {
if (fastField) {
fastField->NextRecord(*this);
}
} else {
HandleRelativePosition(byteCount);
} else if (!AdvanceRecord()) {
return common::nullopt;
}
ch = GetCurrentChar(byteCount, fastField);
ch = GetCurrentCharSlow(byteCount);
}
return ch;
}