diff options
| author | apnadkarni <apnmbx-wits@yahoo.com> | 2023-07-11 16:43:13 (GMT) |
|---|---|---|
| committer | apnadkarni <apnmbx-wits@yahoo.com> | 2023-07-11 16:43:13 (GMT) |
| commit | 04328bc72033c31bd77ac75f27def3e39bd4d117 (patch) | |
| tree | e69c874bafdfec14ad609525965134ba7cb5125b | |
| parent | d852753be2883cd493304baf8fe53eaf7920df1f (diff) | |
| download | tcl-04328bc72033c31bd77ac75f27def3e39bd4d117.zip tcl-04328bc72033c31bd77ac75f27def3e39bd4d117.tar.gz tcl-04328bc72033c31bd77ac75f27def3e39bd4d117.tar.bz2 | |
Tweak last for performance in case of traditional lists.
| -rw-r--r-- | generic/tclExecute.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 84331a3..973ba8e 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -6424,7 +6424,7 @@ TEBCresume( { ForeachInfo *infoPtr; - Tcl_Obj *listPtr; + Tcl_Obj *listPtr, **elements; ForeachVarList *varListPtr; Tcl_Size numLists, listLen, numVars, listTmpDepth; Tcl_Size iterNum, iterMax, iterTmp; @@ -6537,10 +6537,18 @@ TEBCresume( for (i = 0; i < numLists; i++) { varListPtr = infoPtr->varLists[i]; numVars = varListPtr->numVars; + int hasAbstractList; listPtr = OBJ_AT_DEPTH(listTmpDepth); + hasAbstractList = TclObjTypeHasProc(listPtr, indexProc) != 0; DECACHE_STACK_INFO(); - status = Tcl_ListObjLength(interp, listPtr, &listLen); + if (hasAbstractList) { + status = Tcl_ListObjLength(interp, listPtr, &listLen); + elements = NULL; + } else { + status = TclListObjGetElementsM( + interp, listPtr, &listLen, &elements); + } if (status != TCL_OK) { CACHE_STACK_INFO(); goto gotError; @@ -6554,18 +6562,22 @@ TEBCresume( TclNewObj(valuePtr); } else { DECACHE_STACK_INFO(); - status = Tcl_ListObjIndex( - interp, listPtr, valIndex, &valuePtr); - if (status != TCL_OK) { - /* Could happen for abstract lists */ - CACHE_STACK_INFO(); - goto gotError; + if (elements) { + valuePtr = elements[valIndex]; + } else { + status = Tcl_ListObjIndex( + interp, listPtr, valIndex, &valuePtr); + if (status != TCL_OK) { + /* Could happen for abstract lists */ + CACHE_STACK_INFO(); + goto gotError; + } + if (valuePtr == NULL) { + /* Permitted for Tcl_LOI to return NULL */ + TclNewObj(valuePtr); + } } CACHE_STACK_INFO(); - if (valuePtr == NULL) { - /* Permitted for Tcl_LOI to return NULL */ - TclNewObj(valuePtr); - } } varIndex = varListPtr->varIndexes[j]; |
