summaryrefslogtreecommitdiff
path: root/jim-subcmd.c
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2017-09-16 15:31:25 +1000
committerSteve Bennett <steveb@workware.net.au>2017-09-16 15:38:42 +1000
commita77ba6a4dc7cca6f9bf8d917916599bd23dc0af5 (patch)
tree4bc6138d248cc60f175429e9e50aeeb04a5023c2 /jim-subcmd.c
parentfa68b74c218b40476d0c5bac124141c27a00c902 (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.c27
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);