diff --git a/toolchain/lex/tokenized_buffer.cpp b/toolchain/lex/tokenized_buffer.cpp index cd62253ba8b3..9a1cf17aba87 100644 --- a/toolchain/lex/tokenized_buffer.cpp +++ b/toolchain/lex/tokenized_buffer.cpp @@ -300,8 +300,18 @@ class [[clang::internal_linkage]] TokenizedBuffer::Lexer { auto LexHorizontalWhitespace(llvm::StringRef& source_text) -> void { CARBON_DCHECK(source_text.front() == ' ' || source_text.front() == '\t'); NoteWhitespace(); - ++current_column_; - source_text = source_text.drop_front(); + // Handle adjacent whitespace quickly. This comes up frequently for example + // due to indentation. We don't expect *huge* runs, so just use a scalar + // loop. While still scalar, this avoids repeated table dispatch and marking + // whitespace. We use `ssize_t` in the loop for performance. + ssize_t ws_count = 1; + ssize_t size = source_text.size(); + while (ws_count < size && + (source_text[ws_count] == ' ' || source_text[ws_count] == '\t')) { + ++ws_count; + } + current_column_ += ws_count; + source_text = source_text.drop_front(ws_count); } auto LexVerticalWhitespace(llvm::StringRef& source_text) -> void {