mirror of
https://github.com/MidnightCommander/mc
synced 2025-03-13 03:13:08 +03:00
Ticket #1781: some improvements of startup time.
After implementation of keybinding engine and reimplenetation of menu engine, MC starts very slow due to multiple trivial (totally non optimized) search of many values in many arrays. This patch performes the some speedup of MC startup process. Statistics: - startup time without the patch: 0m0.413s - startup time with the patch: 0m0.073s Great thanks to 0xe2.0x9a.0x9b for the original patch. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
edbdaaa50d
commit
15a21a71cd
@ -45,7 +45,7 @@
|
||||
|
||||
#include "keybind.h"
|
||||
|
||||
static const name_keymap_t command_names[] = {
|
||||
static name_keymap_t command_names[] = {
|
||||
#ifdef USE_INTERNAL_EDIT
|
||||
{ "EditNoCommand", CK_Ignore_Key },
|
||||
{ "EditIgnoreKey", CK_Ignore_Key },
|
||||
@ -401,6 +401,9 @@ static const name_keymap_t command_names[] = {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static const size_t num_command_names = sizeof (command_names) /
|
||||
sizeof (command_names[0]) - 1;
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
/* viewer/actions_cmd.c */
|
||||
@ -769,17 +772,39 @@ const global_keymap_t default_input_keymap[] = {
|
||||
{ 0, 0, "" }
|
||||
};
|
||||
|
||||
static int
|
||||
name_keymap_comparator (const void *p1, const void *p2)
|
||||
{
|
||||
const name_keymap_t *m1 = (const name_keymap_t *) p1;
|
||||
const name_keymap_t *m2 = (const name_keymap_t *) p2;
|
||||
|
||||
return str_casecmp (m1->name, m2->name);
|
||||
}
|
||||
|
||||
static void
|
||||
sort_command_names (void)
|
||||
{
|
||||
static gboolean has_been_sorted = FALSE;
|
||||
|
||||
if (!has_been_sorted) {
|
||||
qsort (command_names, num_command_names,
|
||||
sizeof (command_names[0]), &name_keymap_comparator);
|
||||
has_been_sorted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
lookup_action (const char *keyname)
|
||||
{
|
||||
int i;
|
||||
const name_keymap_t key = { keyname, 0 };
|
||||
name_keymap_t *res;
|
||||
|
||||
for (i = 0; command_names [i].name; i++)
|
||||
if (!str_casecmp (command_names [i].name, keyname))
|
||||
return command_names [i].val;
|
||||
sort_command_names ();
|
||||
|
||||
return 0;
|
||||
res = bsearch (&key, command_names, num_command_names,
|
||||
sizeof (command_names[0]), name_keymap_comparator);
|
||||
|
||||
return (res != NULL) ? res->val : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -93,7 +93,7 @@ int use_8th_bit_as_meta = 0;
|
||||
* We use this to allow users to define alternate definitions for
|
||||
* certain keys that may be missing from the terminal database
|
||||
*/
|
||||
key_code_name_t key_name_conv_tab[] = {
|
||||
const key_code_name_t key_name_conv_tab[] = {
|
||||
/* KEY_F(0) is not here, since we are mapping it to f10, so there is no reason
|
||||
to define f0 as well. Also, it makes Learn keys a bunch of problems :( */
|
||||
{ KEY_F (1), "f1", N_("Function key 1"), "F1" },
|
||||
@ -1231,22 +1231,61 @@ check_movement_keys (int key, int page_size, void *data, move_fn backfn,
|
||||
return MSG_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static const size_t key_name_conv_tab_size = sizeof (key_name_conv_tab) /
|
||||
sizeof (key_name_conv_tab[0]) - 1;
|
||||
static key_code_name_t key_name_conv_tab_sorted [sizeof (key_name_conv_tab) /
|
||||
sizeof (key_name_conv_tab[0]) - 1];
|
||||
|
||||
static int
|
||||
key_code_name_comparator (const void *p1, const void *p2)
|
||||
{
|
||||
const key_code_name_t *n1 = (const key_code_name_t *) p1;
|
||||
const key_code_name_t *n2 = (const key_code_name_t *) p2;
|
||||
|
||||
return str_casecmp (n1->name, n2->name);
|
||||
}
|
||||
|
||||
static void
|
||||
sort_key_name_conv_tab (void)
|
||||
{
|
||||
static gboolean has_been_sorted = FALSE;
|
||||
|
||||
if (!has_been_sorted) {
|
||||
int i;
|
||||
for (i = 0; key_name_conv_tab[i].code; i++)
|
||||
key_name_conv_tab_sorted[i] = key_name_conv_tab[i];
|
||||
|
||||
qsort (key_name_conv_tab_sorted, key_name_conv_tab_size,
|
||||
sizeof (key_name_conv_tab_sorted[0]), &key_code_name_comparator);
|
||||
|
||||
has_been_sorted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
lookup_keyname (const char *keyname, int *lc_index)
|
||||
{
|
||||
if (keyname[0] != '\0') {
|
||||
int i;
|
||||
const key_code_name_t key = { 0, keyname, NULL, NULL };
|
||||
key_code_name_t *res;
|
||||
|
||||
if (keyname[1] == '\0') {
|
||||
*lc_index = -1;
|
||||
return (int) keyname[0];
|
||||
}
|
||||
|
||||
for (i = 0; key_name_conv_tab[i].code; i++)
|
||||
if (str_casecmp (key_name_conv_tab[i].name, keyname) == 0) {
|
||||
*lc_index = i;
|
||||
return key_name_conv_tab[i].code;
|
||||
}
|
||||
sort_key_name_conv_tab ();
|
||||
|
||||
res = bsearch (&key, key_name_conv_tab_sorted,
|
||||
key_name_conv_tab_size,
|
||||
sizeof (key_name_conv_tab_sorted[0]),
|
||||
key_code_name_comparator);
|
||||
|
||||
if (res != NULL) {
|
||||
*lc_index = (int) (res - key_name_conv_tab_sorted);
|
||||
return res->code;
|
||||
}
|
||||
}
|
||||
|
||||
*lc_index = -1;
|
||||
|
@ -23,14 +23,14 @@ cb_ret_t check_movement_keys (int key, int page_size, void *data,
|
||||
move_fn backfn, move_fn forfn, move_fn topfn, move_fn bottomfn);
|
||||
int lookup_key (const char *keyname, char **label);
|
||||
|
||||
typedef const struct {
|
||||
typedef struct {
|
||||
int code;
|
||||
const char *name;
|
||||
const char *longname;
|
||||
const char *shortcut;
|
||||
} key_code_name_t;
|
||||
|
||||
extern key_code_name_t key_name_conv_tab[];
|
||||
extern const key_code_name_t key_name_conv_tab[];
|
||||
|
||||
/* mouse support */
|
||||
struct Gpm_Event;
|
||||
|
Loading…
x
Reference in New Issue
Block a user