Skip to content

Commit d51bb0e

Browse files
committed
Optimize S_find_first_nonspace.
We were needlessly redoing things we'd already done. Now we skip the work if the first nonspace is greater than the current offset. This fixes pathological slowdown with deeply nested lists (commonmark#255). For N = 3000, the time goes from over 17s to about 0.7s. Thanks to @mity for diagnosing the problem.
1 parent 55d7b88 commit d51bb0e

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

src/blocks.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -615,22 +615,24 @@ static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) {
615615
char c;
616616
int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP);
617617

618-
parser->first_nonspace = parser->offset;
619-
parser->first_nonspace_column = parser->column;
620-
while ((c = peek_at(input, parser->first_nonspace))) {
621-
if (c == ' ') {
622-
parser->first_nonspace += 1;
623-
parser->first_nonspace_column += 1;
624-
chars_to_tab = chars_to_tab - 1;
625-
if (chars_to_tab == 0) {
618+
if (parser->first_nonspace <= parser->offset) {
619+
parser->first_nonspace = parser->offset;
620+
parser->first_nonspace_column = parser->column;
621+
while ((c = peek_at(input, parser->first_nonspace))) {
622+
if (c == ' ') {
623+
parser->first_nonspace += 1;
624+
parser->first_nonspace_column += 1;
625+
chars_to_tab = chars_to_tab - 1;
626+
if (chars_to_tab == 0) {
627+
chars_to_tab = TAB_STOP;
628+
}
629+
} else if (c == '\t') {
630+
parser->first_nonspace += 1;
631+
parser->first_nonspace_column += chars_to_tab;
626632
chars_to_tab = TAB_STOP;
633+
} else {
634+
break;
627635
}
628-
} else if (c == '\t') {
629-
parser->first_nonspace += 1;
630-
parser->first_nonspace_column += chars_to_tab;
631-
chars_to_tab = TAB_STOP;
632-
} else {
633-
break;
634636
}
635637
}
636638

@@ -1160,6 +1162,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer,
11601162

11611163
parser->offset = 0;
11621164
parser->column = 0;
1165+
parser->first_nonspace = 0;
1166+
parser->first_nonspace_column = 0;
1167+
parser->indent = 0;
11631168
parser->blank = false;
11641169
parser->partially_consumed_tab = false;
11651170

0 commit comments

Comments
 (0)