0
0
mirror of https://github.com/vim/vim.git synced 2025-09-25 03:54:15 -04:00

patch 7.4.1056

Problem:    Don't know why finding spell suggestions is slow.
Solution:   Add some code to gather profiling information.
This commit is contained in:
Bram Moolenaar
2016-01-07 16:22:06 +01:00
parent a61018d7e0
commit ca1fe98517
2 changed files with 108 additions and 0 deletions

View File

@@ -11278,6 +11278,56 @@ suggest_try_special(su)
} }
} }
/*
* Change the 0 to 1 to measure how much time is spent in each state.
* Output is dumped in "suggestprof".
*/
#if 0
# define SUGGEST_PROFILE
proftime_T current;
proftime_T total;
proftime_T times[STATE_FINAL + 1];
long counts[STATE_FINAL + 1];
static void
prof_init(void)
{
for (int i = 0; i <= STATE_FINAL; ++i)
{
profile_zero(&times[i]);
counts[i] = 0;
}
profile_start(&current);
profile_start(&total);
}
/* call before changing state */
static void
prof_store(state_T state)
{
profile_end(&current);
profile_add(&times[state], &current);
++counts[state];
profile_start(&current);
}
# define PROF_STORE(state) prof_store(state);
static void
prof_report(char *name)
{
FILE *fd = fopen("suggestprof", "a");
profile_end(&total);
fprintf(fd, "-----------------------\n");
fprintf(fd, "%s: %s\n", name, profile_msg(&total));
for (int i = 0; i <= STATE_FINAL; ++i)
fprintf(fd, "%d: %s (%ld)\n", i, profile_msg(&times[i]), counts[i]);
fclose(fd);
}
#else
# define PROF_STORE(state)
#endif
/* /*
* Try finding suggestions by adding/removing/swapping letters. * Try finding suggestions by adding/removing/swapping letters.
*/ */
@@ -11309,7 +11359,13 @@ suggest_try_change(su)
continue; continue;
/* Try it for this language. Will add possible suggestions. */ /* Try it for this language. Will add possible suggestions. */
#ifdef SUGGEST_PROFILE
prof_init();
#endif
suggest_trie_walk(su, lp, fword, FALSE); suggest_trie_walk(su, lp, fword, FALSE);
#ifdef SUGGEST_PROFILE
prof_report("try_change");
#endif
} }
} }
@@ -11467,6 +11523,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
/* Always past NUL bytes now. */ /* Always past NUL bytes now. */
n = (int)sp->ts_state; n = (int)sp->ts_state;
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_ENDNUL; sp->ts_state = STATE_ENDNUL;
sp->ts_save_badflags = su->su_badflags; sp->ts_save_badflags = su->su_badflags;
@@ -11510,6 +11567,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
if (sp->ts_curi > len || byts[arridx] != 0) if (sp->ts_curi > len || byts[arridx] != 0)
{ {
/* Past bytes in node and/or past NUL bytes. */ /* Past bytes in node and/or past NUL bytes. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_ENDNUL; sp->ts_state = STATE_ENDNUL;
sp->ts_save_badflags = su->su_badflags; sp->ts_save_badflags = su->su_badflags;
break; break;
@@ -11909,6 +11967,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
#endif #endif
/* Save things to be restored at STATE_SPLITUNDO. */ /* Save things to be restored at STATE_SPLITUNDO. */
sp->ts_save_badflags = su->su_badflags; sp->ts_save_badflags = su->su_badflags;
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_SPLITUNDO; sp->ts_state = STATE_SPLITUNDO;
++depth; ++depth;
@@ -11983,6 +12042,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
byts = pbyts; byts = pbyts;
idxs = pidxs; idxs = pidxs;
sp->ts_prefixdepth = PFD_PREFIXTREE; sp->ts_prefixdepth = PFD_PREFIXTREE;
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_NOPREFIX; sp->ts_state = STATE_NOPREFIX;
} }
} }
@@ -11995,6 +12055,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
su->su_badflags = sp->ts_save_badflags; su->su_badflags = sp->ts_save_badflags;
/* Continue looking for NUL bytes. */ /* Continue looking for NUL bytes. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_START; sp->ts_state = STATE_START;
/* In case we went into the prefix tree. */ /* In case we went into the prefix tree. */
@@ -12012,9 +12073,11 @@ suggest_trie_walk(su, lp, fword, soundfold)
) )
{ {
/* The badword ends, can't use STATE_PLAIN. */ /* The badword ends, can't use STATE_PLAIN. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_DEL; sp->ts_state = STATE_DEL;
break; break;
} }
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_PLAIN; sp->ts_state = STATE_PLAIN;
/*FALLTHROUGH*/ /*FALLTHROUGH*/
@@ -12028,6 +12091,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
{ {
/* Done all bytes at this node, do next state. When still at /* Done all bytes at this node, do next state. When still at
* already changed bytes skip the other tricks. */ * already changed bytes skip the other tricks. */
PROF_STORE(sp->ts_state)
if (sp->ts_fidx >= sp->ts_fidxtry) if (sp->ts_fidx >= sp->ts_fidxtry)
sp->ts_state = STATE_DEL; sp->ts_state = STATE_DEL;
else else
@@ -12184,6 +12248,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
* delete/insert/swap a character. */ * delete/insert/swap a character. */
if (has_mbyte && sp->ts_tcharlen > 0) if (has_mbyte && sp->ts_tcharlen > 0)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL; sp->ts_state = STATE_FINAL;
break; break;
} }
@@ -12191,6 +12256,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
/* /*
* Try skipping one character in the bad word (delete it). * Try skipping one character in the bad word (delete it).
*/ */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_INS_PREP; sp->ts_state = STATE_INS_PREP;
sp->ts_curi = 1; sp->ts_curi = 1;
if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*') if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
@@ -12245,6 +12311,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
{ {
/* If we just deleted a byte then inserting won't make sense, /* If we just deleted a byte then inserting won't make sense,
* a substitute is always cheaper. */ * a substitute is always cheaper. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_SWAP; sp->ts_state = STATE_SWAP;
break; break;
} }
@@ -12256,12 +12323,14 @@ suggest_trie_walk(su, lp, fword, soundfold)
if (sp->ts_curi > byts[n]) if (sp->ts_curi > byts[n])
{ {
/* Only NUL bytes at this node, go to next state. */ /* Only NUL bytes at this node, go to next state. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_SWAP; sp->ts_state = STATE_SWAP;
break; break;
} }
if (byts[n + sp->ts_curi] != NUL) if (byts[n + sp->ts_curi] != NUL)
{ {
/* Found a byte to insert. */ /* Found a byte to insert. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_INS; sp->ts_state = STATE_INS;
break; break;
} }
@@ -12278,6 +12347,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
if (sp->ts_curi > byts[n]) if (sp->ts_curi > byts[n])
{ {
/* Done all bytes at this node, go to next state. */ /* Done all bytes at this node, go to next state. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_SWAP; sp->ts_state = STATE_SWAP;
break; break;
} }
@@ -12349,6 +12419,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
if (c == NUL) if (c == NUL)
{ {
/* End of word, can't swap or replace. */ /* End of word, can't swap or replace. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL; sp->ts_state = STATE_FINAL;
break; break;
} }
@@ -12357,6 +12428,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
* SWAP3 etc. also don't make sense then. */ * SWAP3 etc. also don't make sense then. */
if (!soundfold && !spell_iswordp(p, curwin)) if (!soundfold && !spell_iswordp(p, curwin))
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
break; break;
} }
@@ -12387,6 +12459,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
/* When the second character is NUL we can't swap. */ /* When the second character is NUL we can't swap. */
if (c2 == NUL) if (c2 == NUL)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
break; break;
} }
@@ -12395,6 +12468,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
* Also get here if the second char is not a word character. */ * Also get here if the second char is not a word character. */
if (c == c2) if (c == c2)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_SWAP3; sp->ts_state = STATE_SWAP3;
break; break;
} }
@@ -12406,6 +12480,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
sp->ts_twordlen, tword, fword + sp->ts_fidx, sp->ts_twordlen, tword, fword + sp->ts_fidx,
c, c2); c, c2);
#endif #endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP; sp->ts_state = STATE_UNSWAP;
++depth; ++depth;
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@@ -12425,8 +12500,11 @@ suggest_trie_walk(su, lp, fword, soundfold)
} }
} }
else else
{
/* If this swap doesn't work then SWAP3 won't either. */ /* If this swap doesn't work then SWAP3 won't either. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
}
break; break;
case STATE_UNSWAP: case STATE_UNSWAP:
@@ -12484,6 +12562,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
* Second character may any char: "a.b" -> "b.a" */ * Second character may any char: "a.b" -> "b.a" */
if (c == c3 || c3 == NUL) if (c == c3 || c3 == NUL)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
break; break;
} }
@@ -12495,6 +12574,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
sp->ts_twordlen, tword, fword + sp->ts_fidx, sp->ts_twordlen, tword, fword + sp->ts_fidx,
c, c3); c, c3);
#endif #endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNSWAP3; sp->ts_state = STATE_UNSWAP3;
++depth; ++depth;
#ifdef FEAT_MBYTE #ifdef FEAT_MBYTE
@@ -12515,7 +12595,10 @@ suggest_trie_walk(su, lp, fword, soundfold)
} }
} }
else else
{
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
}
break; break;
case STATE_UNSWAP3: case STATE_UNSWAP3:
@@ -12547,6 +12630,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
{ {
/* Middle char is not a word char, skip the rotate. First and /* Middle char is not a word char, skip the rotate. First and
* third char were already checked at swap and swap3. */ * third char were already checked at swap and swap3. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
break; break;
} }
@@ -12562,6 +12646,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
sp->ts_twordlen, tword, fword + sp->ts_fidx, sp->ts_twordlen, tword, fword + sp->ts_fidx,
p[0], p[1], p[2]); p[0], p[1], p[2]);
#endif #endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3L; sp->ts_state = STATE_UNROT3L;
++depth; ++depth;
p = fword + sp->ts_fidx; p = fword + sp->ts_fidx;
@@ -12587,7 +12672,10 @@ suggest_trie_walk(su, lp, fword, soundfold)
} }
} }
else else
{
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
}
break; break;
case STATE_UNROT3L: case STATE_UNROT3L:
@@ -12623,6 +12711,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
sp->ts_twordlen, tword, fword + sp->ts_fidx, sp->ts_twordlen, tword, fword + sp->ts_fidx,
p[0], p[1], p[2]); p[0], p[1], p[2]);
#endif #endif
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_UNROT3R; sp->ts_state = STATE_UNROT3R;
++depth; ++depth;
p = fword + sp->ts_fidx; p = fword + sp->ts_fidx;
@@ -12648,7 +12737,10 @@ suggest_trie_walk(su, lp, fword, soundfold)
} }
} }
else else
{
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_INI; sp->ts_state = STATE_REP_INI;
}
break; break;
case STATE_UNROT3R: case STATE_UNROT3R:
@@ -12684,6 +12776,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
|| sp->ts_score + SCORE_REP >= su->su_maxscore || sp->ts_score + SCORE_REP >= su->su_maxscore
|| sp->ts_fidx < sp->ts_fidxtry) || sp->ts_fidx < sp->ts_fidxtry)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL; sp->ts_state = STATE_FINAL;
break; break;
} }
@@ -12697,10 +12790,12 @@ suggest_trie_walk(su, lp, fword, soundfold)
if (sp->ts_curi < 0) if (sp->ts_curi < 0)
{ {
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL; sp->ts_state = STATE_FINAL;
break; break;
} }
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP; sp->ts_state = STATE_REP;
/*FALLTHROUGH*/ /*FALLTHROUGH*/
@@ -12733,6 +12828,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
ftp->ft_from, ftp->ft_to); ftp->ft_from, ftp->ft_to);
#endif #endif
/* Need to undo this afterwards. */ /* Need to undo this afterwards. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP_UNDO; sp->ts_state = STATE_REP_UNDO;
/* Change the "from" to the "to" string. */ /* Change the "from" to the "to" string. */
@@ -12754,8 +12850,11 @@ suggest_trie_walk(su, lp, fword, soundfold)
} }
if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP) if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
{
/* No (more) matches. */ /* No (more) matches. */
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_FINAL; sp->ts_state = STATE_FINAL;
}
break; break;
@@ -12775,6 +12874,7 @@ suggest_trie_walk(su, lp, fword, soundfold)
repextra -= tl - fl; repextra -= tl - fl;
} }
mch_memmove(p, ftp->ft_from, fl); mch_memmove(p, ftp->ft_from, fl);
PROF_STORE(sp->ts_state)
sp->ts_state = STATE_REP; sp->ts_state = STATE_REP;
break; break;
@@ -13287,7 +13387,13 @@ suggest_try_soundalike(su)
/* try all kinds of inserts/deletes/swaps/etc. */ /* try all kinds of inserts/deletes/swaps/etc. */
/* TODO: also soundfold the next words, so that we can try joining /* TODO: also soundfold the next words, so that we can try joining
* and splitting */ * and splitting */
#ifdef SUGGEST_PROFILE
prof_init();
#endif
suggest_trie_walk(su, lp, salword, TRUE); suggest_trie_walk(su, lp, salword, TRUE);
#ifdef SUGGEST_PROFILE
prof_report("soundalike");
#endif
} }
} }
} }

View File

@@ -741,6 +741,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1056,
/**/ /**/
1055, 1055,
/**/ /**/