diff options
author | John MacFarlane <jgm@berkeley.edu> | 2018-04-14 21:39:53 -0700 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2018-04-14 21:41:59 -0700 |
commit | d51bb0e45be412f1f36b010f7458d2c392e28f2b (patch) | |
tree | 13917a58cf4e4ccc8e2c114da54f7ef4c7e29b41 /src | |
parent | 55d7b8808a7bba08345bcc94b7a462176c182fc9 (diff) |
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 (#255). For N = 3000, the time goes from over
17s to about 0.7s.
Thanks to @mity for diagnosing the problem.
Diffstat (limited to 'src')
-rw-r--r-- | src/blocks.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/src/blocks.c b/src/blocks.c index 3e32535..bdd819e 100644 --- a/src/blocks.c +++ b/src/blocks.c @@ -615,22 +615,24 @@ static void S_find_first_nonspace(cmark_parser *parser, cmark_chunk *input) { char c; int chars_to_tab = TAB_STOP - (parser->column % TAB_STOP); - parser->first_nonspace = parser->offset; - parser->first_nonspace_column = parser->column; - while ((c = peek_at(input, parser->first_nonspace))) { - if (c == ' ') { - parser->first_nonspace += 1; - parser->first_nonspace_column += 1; - chars_to_tab = chars_to_tab - 1; - if (chars_to_tab == 0) { + if (parser->first_nonspace <= parser->offset) { + parser->first_nonspace = parser->offset; + parser->first_nonspace_column = parser->column; + while ((c = peek_at(input, parser->first_nonspace))) { + if (c == ' ') { + parser->first_nonspace += 1; + parser->first_nonspace_column += 1; + chars_to_tab = chars_to_tab - 1; + if (chars_to_tab == 0) { + chars_to_tab = TAB_STOP; + } + } else if (c == '\t') { + parser->first_nonspace += 1; + parser->first_nonspace_column += chars_to_tab; chars_to_tab = TAB_STOP; + } else { + break; } - } else if (c == '\t') { - parser->first_nonspace += 1; - parser->first_nonspace_column += chars_to_tab; - chars_to_tab = TAB_STOP; - } else { - break; } } @@ -1160,6 +1162,9 @@ static void S_process_line(cmark_parser *parser, const unsigned char *buffer, parser->offset = 0; parser->column = 0; + parser->first_nonspace = 0; + parser->first_nonspace_column = 0; + parser->indent = 0; parser->blank = false; parser->partially_consumed_tab = false; |