diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-02-20 22:04:32 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-02-20 22:04:32 +0100 |
commit | 38f08e76acf7d21bb34cf8f79f0f82eb63cdc987 (patch) | |
tree | aa303c467edd65762eb39e19843d8112f035f164 | |
parent | 35856718881834a76225530d502c68fdec6584cf (diff) | |
download | vim-git-38f08e76acf7d21bb34cf8f79f0f82eb63cdc987.tar.gz |
patch 8.1.0958: compiling weird regexp pattern is very slowv8.1.0958
Problem: Compiling weird regexp pattern is very slow.
Solution: When reallocating post list increase size by 50%. (Kuang-che Wu,
closes #4012) Make assert_inrange() accept float values.
-rw-r--r-- | src/eval.c | 75 | ||||
-rw-r--r-- | src/regexp_nfa.c | 5 | ||||
-rw-r--r-- | src/testdir/test_assert.vim | 16 | ||||
-rw-r--r-- | src/testdir/test_regexp_latin.vim | 11 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 84 insertions, 25 deletions
diff --git a/src/eval.c b/src/eval.c index f66d29650..046688f0b 100644 --- a/src/eval.c +++ b/src/eval.c @@ -9365,32 +9365,65 @@ assert_inrange(typval_T *argvars) { garray_T ga; int error = FALSE; - varnumber_T lower = tv_get_number_chk(&argvars[0], &error); - varnumber_T upper = tv_get_number_chk(&argvars[1], &error); - varnumber_T actual = tv_get_number_chk(&argvars[2], &error); char_u *tofree; char msg[200]; char_u numbuf[NUMBUFLEN]; - if (error) - return 0; - if (actual < lower || actual > upper) +#ifdef FEAT_FLOAT + if (argvars[0].v_type == VAR_FLOAT + || argvars[1].v_type == VAR_FLOAT + || argvars[2].v_type == VAR_FLOAT) { - prepare_assert_error(&ga); - if (argvars[3].v_type != VAR_UNKNOWN) + float_T flower = tv_get_float(&argvars[0]); + float_T fupper = tv_get_float(&argvars[1]); + float_T factual = tv_get_float(&argvars[2]); + + if (factual < flower || factual > fupper) { - ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); - vim_free(tofree); + prepare_assert_error(&ga); + if (argvars[3].v_type != VAR_UNKNOWN) + { + ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); + vim_free(tofree); + } + else + { + vim_snprintf(msg, 200, "Expected range %g - %g, but got %g", + flower, fupper, factual); + ga_concat(&ga, (char_u *)msg); + } + assert_error(&ga); + ga_clear(&ga); + return 1; } - else + } + else +#endif + { + varnumber_T lower = tv_get_number_chk(&argvars[0], &error); + varnumber_T upper = tv_get_number_chk(&argvars[1], &error); + varnumber_T actual = tv_get_number_chk(&argvars[2], &error); + + if (error) + return 0; + if (actual < lower || actual > upper) { - vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld", + prepare_assert_error(&ga); + if (argvars[3].v_type != VAR_UNKNOWN) + { + ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); + vim_free(tofree); + } + else + { + vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld", (long)lower, (long)upper, (long)actual); - ga_concat(&ga, (char_u *)msg); + ga_concat(&ga, (char_u *)msg); + } + assert_error(&ga); + ga_clear(&ga); + return 1; } - assert_error(&ga); - ga_clear(&ga); - return 1; } return 0; } @@ -9822,14 +9855,8 @@ typval_compare( { float_T f1, f2; - if (typ1->v_type == VAR_FLOAT) - f1 = typ1->vval.v_float; - else - f1 = tv_get_number(typ1); - if (typ2->v_type == VAR_FLOAT) - f2 = typ2->vval.v_float; - else - f2 = tv_get_number(typ2); + f1 = tv_get_float(typ1); + f2 = tv_get_float(typ2); n1 = FALSE; switch (type) { diff --git a/src/regexp_nfa.c b/src/regexp_nfa.c index 9633791bc..333c006f4 100644 --- a/src/regexp_nfa.c +++ b/src/regexp_nfa.c @@ -509,10 +509,13 @@ nfa_get_match_text(nfa_state_T *start) realloc_post_list(void) { int nstate_max = (int)(post_end - post_start); - int new_max = nstate_max + 1000; + int new_max; int *new_start; int *old_start; + // For weird patterns the number of states can be very high. Increasing by + // 50% seems a reasonable compromise between memory use and speed. + new_max = nstate_max * 3 / 2; new_start = (int *)lalloc(new_max * sizeof(int), TRUE); if (new_start == NULL) return FAIL; diff --git a/src/testdir/test_assert.vim b/src/testdir/test_assert.vim index 298a6db15..7df641c6a 100644 --- a/src/testdir/test_assert.vim +++ b/src/testdir/test_assert.vim @@ -190,6 +190,22 @@ func Test_assert_inrange() call remove(v:errors, 0) call assert_fails('call assert_inrange(1, 1)', 'E119:') + + if has('float') + call assert_equal(0, assert_inrange(7.0, 7, 7)) + call assert_equal(0, assert_inrange(7, 7.0, 7)) + call assert_equal(0, assert_inrange(7, 7, 7.0)) + call assert_equal(0, assert_inrange(5, 7, 5.0)) + call assert_equal(0, assert_inrange(5, 7, 6.0)) + call assert_equal(0, assert_inrange(5, 7, 7.0)) + + call assert_equal(1, assert_inrange(5, 7, 4.0)) + call assert_match("Expected range 5.0 - 7.0, but got 4.0", v:errors[0]) + call remove(v:errors, 0) + call assert_equal(1, assert_inrange(5, 7, 8.0)) + call assert_match("Expected range 5.0 - 7.0, but got 8.0", v:errors[0]) + call remove(v:errors, 0) + endif endfunc func Test_assert_with_msg() diff --git a/src/testdir/test_regexp_latin.vim b/src/testdir/test_regexp_latin.vim index d603acdbc..7a4d98f9a 100644 --- a/src/testdir/test_regexp_latin.vim +++ b/src/testdir/test_regexp_latin.vim @@ -130,3 +130,14 @@ func Test_range_with_newline() call assert_equal(0, search("[ -*\\t-\\n]")) bwipe! endfunc + +func Test_pattern_compile_speed() + if !exists('+spellcapcheck') || !has('reltime') + return + endif + let start = reltime() + " this used to be very slow, not it should be about a second + set spc=\\v(((((Nxxxxxxx&&xxxx){179})+)+)+){179} + call assert_inrange(0.01, 10.0, reltimefloat(reltime(start))) + set spc= +endfunc diff --git a/src/version.c b/src/version.c index 5a3a53c38..b2d76b752 100644 --- a/src/version.c +++ b/src/version.c @@ -780,6 +780,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 958, +/**/ 957, /**/ 956, |