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:
Andrew Borodin 2009-11-03 19:39:16 +03:00
parent edbdaaa50d
commit 15a21a71cd
3 changed files with 79 additions and 15 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;