vim-patch:8.0.1284: loading file type detection slows down startup

Problem:    Loading file type detection slows down startup.
Solution:   Store the last pattern of an autocommand event to make appending
            quicker.
462455ee8b
This commit is contained in:
Justin M. Keyes
2018-04-02 23:30:30 +02:00
parent eb00fc0cf0
commit e25e552a3d

View File

@@ -1,9 +1,7 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check // This is an open source non-commercial project. Dear PVS-Studio, please check
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
/* // fileio.c: read from and write to a file
* fileio.c: read from and write to a file
*/
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@@ -65,57 +63,62 @@
#define BUFSIZE 8192 /* size of normal write buffer */ #define BUFSIZE 8192 /* size of normal write buffer */
#define SMBUFSIZE 256 /* size of emergency write buffer */ #define SMBUFSIZE 256 /* size of emergency write buffer */
/* //
* The autocommands are stored in a list for each event. // The autocommands are stored in a list for each event.
* Autocommands for the same pattern, that are consecutive, are joined // Autocommands for the same pattern, that are consecutive, are joined
* together, to avoid having to match the pattern too often. // together, to avoid having to match the pattern too often.
* The result is an array of Autopat lists, which point to AutoCmd lists: // The result is an array of Autopat lists, which point to AutoCmd lists:
* //
* first_autopat[0] --> Autopat.next --> Autopat.next --> NULL // last_autopat[0] -----------------------------+
* Autopat.cmds Autopat.cmds // V
* | | // first_autopat[0] --> Autopat.next --> Autopat.next --> NULL
* V V // Autopat.cmds Autopat.cmds
* AutoCmd.next AutoCmd.next // | |
* | | // V V
* V V // AutoCmd.next AutoCmd.next
* AutoCmd.next NULL // | |
* | // V V
* V // AutoCmd.next NULL
* NULL // |
* // V
* first_autopat[1] --> Autopat.next --> NULL // NULL
* Autopat.cmds //
* | // last_autopat[1] --------+
* V // V
* AutoCmd.next // first_autopat[1] --> Autopat.next --> NULL
* | // Autopat.cmds
* V // |
* NULL // V
* etc. // AutoCmd.next
* // |
* The order of AutoCmds is important, this is the order in which they were // V
* defined and will have to be executed. // NULL
*/ // etc.
//
// The order of AutoCmds is important, this is the order in which they were
// defined and will have to be executed.
//
typedef struct AutoCmd { typedef struct AutoCmd {
char_u *cmd; /* The command to be executed (NULL char_u *cmd; // The command to be executed (NULL
when command has been removed) */ // when command has been removed)
char nested; /* If autocommands nest here */ char nested; // If autocommands nest here
char last; /* last command in list */ char last; // last command in list
scid_T scriptID; /* script ID where defined */ scid_T scriptID; // script ID where defined
struct AutoCmd *next; /* Next AutoCmd in list */ struct AutoCmd *next; // Next AutoCmd in list
} AutoCmd; } AutoCmd;
typedef struct AutoPat { typedef struct AutoPat {
char_u *pat; /* pattern as typed (NULL when pattern struct AutoPat *next; // next AutoPat in AutoPat list; MUST
has been removed) */ // be the first entry
regprog_T *reg_prog; /* compiled regprog for pattern */ char_u *pat; // pattern as typed (NULL when pattern
AutoCmd *cmds; /* list of commands to do */ // has been removed)
struct AutoPat *next; /* next AutoPat in AutoPat list */ regprog_T *reg_prog; // compiled regprog for pattern
int group; /* group ID */ AutoCmd *cmds; // list of commands to do
int patlen; /* strlen() of pat */ int group; // group ID
int buflocal_nr; /* !=0 for buffer-local AutoPat */ int patlen; // strlen() of pat
char allow_dirs; /* Pattern may match whole path */ int buflocal_nr; // !=0 for buffer-local AutoPat
char last; /* last pattern for apply_autocmds() */ char allow_dirs; // Pattern may match whole path
char last; // last pattern for apply_autocmds()
} AutoPat; } AutoPat;
/* /*
@@ -226,6 +229,15 @@ void filemess(buf_T *buf, char_u *name, char_u *s, int attr)
msg_scrolled_ign = FALSE; msg_scrolled_ign = FALSE;
} }
static AutoPat *last_autopat[NUM_EVENTS] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/* /*
* Read lines from file "fname" into the buffer after line "from". * Read lines from file "fname" into the buffer after line "from".
* *
@@ -5528,6 +5540,15 @@ static void au_cleanup(void)
/* remove the pattern if it has been marked for deletion */ /* remove the pattern if it has been marked for deletion */
if (ap->pat == NULL) { if (ap->pat == NULL) {
if (ap->next == NULL) {
if (prev_ap == &(first_autopat[(int)event])) {
last_autopat[(int)event] = NULL;
} else {
// this depends on the "next" field being the first in
// the struct
last_autopat[(int)event] = (AutoPat *)prev_ap;
}
}
*prev_ap = ap->next; *prev_ap = ap->next;
vim_regfree(ap->reg_prog); vim_regfree(ap->reg_prog);
xfree(ap); xfree(ap);
@@ -6120,10 +6141,13 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
patlen = (int)STRLEN(buflocal_pat); /* but not endpat */ patlen = (int)STRLEN(buflocal_pat); /* but not endpat */
} }
/* // Find AutoPat entries with this pattern. When adding a command it
* Find AutoPat entries with this pattern. // always goes at or after the last one, so start at the end.
*/ if (!forceit && *cmd != NUL && last_autopat[(int)event] != NULL) {
prev_ap = &last_autopat[(int)event];
} else {
prev_ap = &first_autopat[(int)event]; prev_ap = &first_autopat[(int)event];
}
while ((ap = *prev_ap) != NULL) { while ((ap = *prev_ap) != NULL) {
if (ap->pat != NULL) { if (ap->pat != NULL) {
/* Accept a pattern when: /* Accept a pattern when:
@@ -6209,6 +6233,7 @@ static int do_autocmd_event(event_T event, char_u *pat, int nested, char_u *cmd,
} }
ap->cmds = NULL; ap->cmds = NULL;
*prev_ap = ap; *prev_ap = ap;
last_autopat[(int)event] = ap;
ap->next = NULL; ap->next = NULL;
if (group == AUGROUP_ALL) if (group == AUGROUP_ALL)
ap->group = current_augroup; ap->group = current_augroup;