From 1c3bd77ba717f05686929f65fc2ed8087f71f279 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 bd86d34446c9b2aea38830bd43f24750a67d52e2 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 4ad182db909f346b0e4dc54ffc41abecaf0fad98 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