|
From: Porter, D. <don...@ni...> - 2013-01-17 18:57:14
|
Remember that [string length] returns the number of characters in the string. That information is not stored anywhere in the Tcl_Obj struct. (objPtr->length is in bytes, not chars) The shimmer happens so that we have someplace to store the computed length in chars, so when it's asked for again we don't have to compute it again. Looking at the 8.4 source code, it does the same. You should not see any difference in the shimmer pattern moving from 8.4 to 8.5. Tcl_GetCharLength() calls SetStringFromAny() which shimmers. Don't you see that in your examples? DGP ________________________________________ From: Brian Griffin [bri...@me...] Sent: Thursday, January 17, 2013 1:22 PM To: Tcl Core List Subject: [TCLCORE] Agressive shimmering It seems that tcl 8.5 is more aggressively simmering Tcl_Obj's to a StringObj then in 8.4. This is causing problems and concerns here. The problems are ultimately self induced, but the concerns are still valid. Why is it that [string] operations blindly force conversion when there is already a string present in the obj? This seems to defeat the purpose of the Tcl_Obj! If the string representation is not going to be used, why would an alternative internal representation ever bother to produce one? (rhetorical question) Specifically, the [string length] operation is blowing away any internal representation regardless of whether a string (->bytes != NULL) is present or not. This seems unnecessary, overly aggressive, and counter intuitive given the fundamental design goal of Tcl_Obj to "behave like strings but also hold an internal representation that can be manipulated more efficiently". Blowing away the list representation just to find out the length of the string representation is darn less efficient in my book, not more. Can anyone justify this behavior? Does anyone else think that it's not right? -Brian % set x [list a b c] a b c % tcl::unsupported::DumpTclObj $x refCount = 2 bytes = 0x8ff3188 length = 5 typePtr = 0x8d21e94 (list) internal.ptr1 = 0x8ff2228 internal.ptr2 = (nil) % string length $x 5 % tcl::unsupported::DumpTclObj $x refCount = 2 bytes = 0x8ff3188 length = 5 typePtr = 0x8d221b0 (string) internal.ptr1 = 0x8ff3368 internal.ptr2 = (nil) % lindex $x 1 b % tcl::unsupported::DumpTclObj $x refCount = 2 bytes = 0x8ff3188 length = 5 typePtr = 0x8d21e94 (list) internal.ptr1 = 0x8ff2228 internal.ptr2 = (nil) |