From a2d8880b712a72bc6ecdbb39d6d9b865731bee89 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 May 2011 18:00:54 +0000 Subject: Disable all the special case code in place to prevent allocation of a List struct for empty lists as much as possible. The value of this avoidance is not clear to me. Hoping it can be demonstrated (or refuted) with both variants side by side in the code history tree. --- generic/tclListObj.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index c4061b3..b525260 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -461,7 +461,7 @@ Tcl_ListObjGetElements( if (listPtr->typePtr != &tclListType) { int result, length; - +#if 0 /* * Don't get the string version of a dictionary; that transformation * is not lossy, but is expensive. @@ -477,7 +477,7 @@ Tcl_ListObjGetElements( *objvPtr = NULL; return TCL_OK; } - +#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -588,7 +588,7 @@ Tcl_ListObjAppendElement( } if (listPtr->typePtr != &tclListType) { int result, length; - +#if 0 if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { @@ -598,7 +598,7 @@ Tcl_ListObjAppendElement( Tcl_SetListObj(listPtr, 1, &objPtr); return TCL_OK; } - +#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -703,7 +703,7 @@ Tcl_ListObjIndex( if (listPtr->typePtr != &tclListType) { int result, length; - +#if 0 if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { @@ -713,7 +713,7 @@ Tcl_ListObjIndex( *objPtrPtr = NULL; return TCL_OK; } - +#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -762,7 +762,7 @@ Tcl_ListObjLength( if (listPtr->typePtr != &tclListType) { int result, length; - +#if 0 if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); /* @@ -781,7 +781,7 @@ Tcl_ListObjLength( *intPtr = 0; return TCL_OK; } - +#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -850,7 +850,7 @@ Tcl_ListObjReplace( } if (listPtr->typePtr != &tclListType) { int length; - +#if 0 if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { @@ -863,12 +863,15 @@ Tcl_ListObjReplace( return TCL_OK; } } else { +#endif int result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; } +#if 0 } +#endif } /* @@ -1552,7 +1555,7 @@ TclListObjSetElement( } if (listPtr->typePtr != &tclListType) { int length, result; - +#if 0 if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { @@ -1565,6 +1568,7 @@ TclListObjSetElement( } return TCL_ERROR; } +#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; -- cgit v0.12 From b6ec9192774ed0dd9febdfd0939490faa2ebd360 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 9 May 2011 13:26:09 +0000 Subject: A different technique to more precisely identify the optimization case. --- generic/tclListObj.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index b525260..536fae8 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -460,8 +460,8 @@ Tcl_ListObjGetElements( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { - int result, length; #if 0 + int result, length; /* * Don't get the string version of a dictionary; that transformation * is not lossy, but is expensive. @@ -473,11 +473,15 @@ Tcl_ListObjGetElements( (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + int result; + + if (listPtr->bytes == tclEmptyStringRep) { +#endif *objcPtr = 0; *objvPtr = NULL; return TCL_OK; } -#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -587,18 +591,22 @@ Tcl_ListObjAppendElement( Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement"); } if (listPtr->typePtr != &tclListType) { - int result, length; #if 0 + int result, length; if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + int result; + + if (listPtr->bytes == tclEmptyStringRep) { +#endif Tcl_SetListObj(listPtr, 1, &objPtr); return TCL_OK; } -#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -702,18 +710,22 @@ Tcl_ListObjIndex( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { - int result, length; #if 0 + int result, length; if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + int result; + + if (listPtr->bytes == tclEmptyStringRep) { +#endif *objPtrPtr = NULL; return TCL_OK; } -#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -761,8 +773,8 @@ Tcl_ListObjLength( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { - int result, length; #if 0 + int result, length; if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); /* @@ -778,10 +790,14 @@ Tcl_ListObjLength( (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + int result; + + if (listPtr->bytes == tclEmptyStringRep) { +#endif *intPtr = 0; return TCL_OK; } -#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; @@ -849,29 +865,30 @@ Tcl_ListObjReplace( Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace"); } if (listPtr->typePtr != &tclListType) { - int length; #if 0 + int length; if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + if (listPtr->bytes == tclEmptyStringRep) { +#endif + if (objc) { Tcl_SetListObj(listPtr, objc, NULL); } else { return TCL_OK; } } else { -#endif int result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; } -#if 0 } -#endif } /* @@ -1554,21 +1571,25 @@ TclListObjSetElement( Tcl_Panic("%s called with shared object", "TclListObjSetElement"); } if (listPtr->typePtr != &tclListType) { - int length, result; #if 0 + int length, result; if (listPtr->typePtr == &tclDictType) { (void) Tcl_DictObjSize(NULL, listPtr, &length); } else { (void) TclGetStringFromObj(listPtr, &length); } if (!length) { +#else + int result; + + if (listPtr->bytes == tclEmptyStringRep) { +#endif if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", -1)); } return TCL_ERROR; } -#endif result = SetListFromAny(interp, listPtr); if (result != TCL_OK) { return result; -- cgit v0.12 From e963bdb8c5bc45baab4b8850108b80d1c001dfdf Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 9 May 2011 13:46:02 +0000 Subject: Remove the old implementation. --- generic/tclListObj.c | 75 ---------------------------------------------------- 1 file changed, 75 deletions(-) diff --git a/generic/tclListObj.c b/generic/tclListObj.c index 536fae8..c2e9c78 100644 --- a/generic/tclListObj.c +++ b/generic/tclListObj.c @@ -460,24 +460,9 @@ Tcl_ListObjGetElements( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { -#if 0 - int result, length; - /* - * Don't get the string version of a dictionary; that transformation - * is not lossy, but is expensive. - */ - - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else int result; if (listPtr->bytes == tclEmptyStringRep) { -#endif *objcPtr = 0; *objvPtr = NULL; return TCL_OK; @@ -591,19 +576,9 @@ Tcl_ListObjAppendElement( Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement"); } if (listPtr->typePtr != &tclListType) { -#if 0 - int result, length; - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else int result; if (listPtr->bytes == tclEmptyStringRep) { -#endif Tcl_SetListObj(listPtr, 1, &objPtr); return TCL_OK; } @@ -710,19 +685,9 @@ Tcl_ListObjIndex( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { -#if 0 - int result, length; - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else int result; if (listPtr->bytes == tclEmptyStringRep) { -#endif *objPtrPtr = NULL; return TCL_OK; } @@ -773,28 +738,9 @@ Tcl_ListObjLength( register List *listRepPtr; if (listPtr->typePtr != &tclListType) { -#if 0 - int result, length; - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - /* - * It's tempting to just report 2*length as the list length - * of this dict, but arguably that's false since the max sizes - * for dicts and lists are not the same, so some dicts don't - * actually convert to lists, and it's good to get that error - * back from the SetListFromAny() call below instead of a false - * indication we can treat the value as a list. ([llength $val] - * often used as a "listiness" test) - */ - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else int result; if (listPtr->bytes == tclEmptyStringRep) { -#endif *intPtr = 0; return TCL_OK; } @@ -865,18 +811,7 @@ Tcl_ListObjReplace( Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace"); } if (listPtr->typePtr != &tclListType) { -#if 0 - int length; - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else if (listPtr->bytes == tclEmptyStringRep) { -#endif - if (objc) { Tcl_SetListObj(listPtr, objc, NULL); } else { @@ -1571,19 +1506,9 @@ TclListObjSetElement( Tcl_Panic("%s called with shared object", "TclListObjSetElement"); } if (listPtr->typePtr != &tclListType) { -#if 0 - int length, result; - if (listPtr->typePtr == &tclDictType) { - (void) Tcl_DictObjSize(NULL, listPtr, &length); - } else { - (void) TclGetStringFromObj(listPtr, &length); - } - if (!length) { -#else int result; if (listPtr->bytes == tclEmptyStringRep) { -#endif if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("list index out of range", -1)); -- cgit v0.12