diff options
author | Steve Bennett <steveb@workware.net.au> | 2017-09-16 15:31:25 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2017-09-16 15:38:42 +1000 |
commit | a77ba6a4dc7cca6f9bf8d917916599bd23dc0af5 (patch) | |
tree | 4bc6138d248cc60f175429e9e50aeeb04a5023c2 /jim-subcmd.c | |
parent | fa68b74c218b40476d0c5bac124141c27a00c902 (diff) |
perf: cache the result of successful subcmd lookup
Speeds up jim-subcmd commands such as array, clock, file, aio
Signed-off-by: Steve Bennett <steveb@workware.net.au>
Diffstat (limited to 'jim-subcmd.c')
-rw-r--r-- | jim-subcmd.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/jim-subcmd.c b/jim-subcmd.c index 1371dd4..1a090d5 100644 --- a/jim-subcmd.c +++ b/jim-subcmd.c @@ -70,6 +70,18 @@ static void set_wrong_args(Jim_Interp *interp, const jim_subcmd_type * command_t Jim_AppendStrings(interp, Jim_GetResult(interp), "\"", NULL); } +/* internal rep is stored in ptrIntvalue + * ptr = command_table + * int1 = index + */ +static const Jim_ObjType subcmdLookupObjType = { + "subcmd-lookup", + NULL, + NULL, + NULL, + JIM_TYPE_REFERENCES +}; + const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type * command_table, int argc, Jim_Obj *const *argv) { @@ -88,6 +100,14 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type cmd = argv[1]; + /* Use cached lookup if possible */ + if (cmd->typePtr == &subcmdLookupObjType) { + if (cmd->internalRep.ptrIntValue.ptr == command_table) { + ct = command_table + cmd->internalRep.ptrIntValue.int1; + goto found; + } + } + /* Check for the help command */ if (Jim_CompareStringImmediate(interp, cmd, "-help")) { if (argc == 2) { @@ -155,6 +175,13 @@ const jim_subcmd_type *Jim_ParseSubCmd(Jim_Interp *interp, const jim_subcmd_type return &dummy_subcmd; } + /* Cache the result for a successful non-help lookup */ + Jim_FreeIntRep(interp, cmd); + cmd->typePtr = &subcmdLookupObjType; + cmd->internalRep.ptrIntValue.ptr = (void *)command_table; + cmd->internalRep.ptrIntValue.int1 = ct - command_table; + +found: /* Check the number of args */ if (argc - 2 < ct->minargs || (ct->maxargs >= 0 && argc - 2 > ct->maxargs)) { Jim_SetResultString(interp, "wrong # args: should be \"", -1); |