Re: [naviserver-devel] Tcl object handling
Hi, Maybe someon is interested in some findings about the problem with Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); i just workd through the xotcl c code, and found indeed a potential source for the problem (in the non-frequently used XOTclOIsMixinMethod() call) and fixed it. It is my understanding that the problem with the shared result object happens only when some c-code sets the result with an shared object somewhere after the start of the command (e.g. doing an eval). Simple commands are still safe. When doing some tests, it shows that the version with Tcl_NewIntObj() is measurable slower than the version with the reused result object (no wonder) but as well slower than the version with Tcl_ResetResult(). For the following test, i measured the total time of calling a simple xotcl command (... info superclass someclass), including all xotcl overhead. The xotcl command was called 100.000 times, the test was performed 100 times to get useful granularity from the timer. puts [time {time $cmd 10} 100] Tcl_SetIntObj(Tcl_GetObjResult(in), 1);168524,55100,00% Tcl_SetObjResult(in, Tcl_NewIntObj(1))186699,12110,78% Reset Tcl_SetIntObj(Tcl_GetObjResult(in), 1);178237,24105,76% The timings are from a PowerPC G5 with 2.1 GHz. This shows that the runtime of the xotcl command is 10% slower with NewIntObj() and 5% slower with ResetResult() than the runtime of the command with setting the result obj. I get similar timings for other commands like ... isobject ... as well. The differences are bigger than expected. Certainly, for some applications that might not matter -gustaf neumann
Re: [naviserver-devel] Tcl object handling
On 25.09.2006, at 11:40, Gustaf Neumann wrote: When doing some tests, it shows that the version with Tcl_NewIntObj() is measurable slower than the version with the reused result object (no wonder) but as well slower than the version with Tcl_ResetResult(). For the following test, i measured the total time of calling a simple xotcl command (... info superclass someclass), including all xotcl overhead. The xotcl command was called 100.000 times, the test was performed 100 times to get useful granularity from the timer. puts [time {time $cmd 10} 100] Tcl_SetIntObj(Tcl_GetObjResult(in), 1);168524,55100,00% Tcl_SetObjResult(in, Tcl_NewIntObj(1))186699,12110,78% Reset Tcl_SetIntObj(Tcl_GetObjResult(in), 1);178237,24 105,76% The timings are from a PowerPC G5 with 2.1 GHz. This shows that the runtime of the xotcl command is 10% slower with NewIntObj() and 5% slower with ResetResult() than the runtime of the command with setting the result obj. I get similar timings for other commands like ... isobject ... as well. The differences are bigger than expected. Certainly, for some applications that might not matter hmhmhmhm... this is most interesting. I would have to see how and Tcl_ResetResult followed by Tcl_SetWhatever can be slower than Tcl_SetObjResult. I would bet two are the same (have to do the same work, rather, Tcl_ResetResult must do even more). This is most interesting...
[naviserver-devel] Tcl object handling
Hi! After I have observed some very subtle and hard-to-reproduce bugs in our app, I found out that Tcl object handling in some places in NS code, although by the book is really a source of trouble. Like: Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); /* Unsafe? */ This construct assumes that object stored in the interp result is not shared. I do not know, and I will have to make the journey on Tcl core list, if it is possible to have a shared object in the interp result or not, but it seems to me that it is. OR, there is some other source or problem which I do not know. But, when I modify it to look like: Tcl_SetObjResult(interp, Tcl_NewIntObj(1));/* Safe! */ then all works fine. This is not only the case with the Int but with all other object types as well. Difference between the two is that the first one saves creation of a new Tcl object, as it re-uses the one stored in the interp result. But, creation of Tcl object is relatively cheap operation (pop from the list) so there is not really much that it's saved. I have gone thru the sources and replaced all those problematic spots and would kindly ask any C-code commiter to pay attention to the above. Until we explicitly find out what is happening and why, I'd consider the above construct unsafe and would refrain from using it. Thanks Zoran
Re: [naviserver-devel] Tcl object handling
Zoran Vasiljevic schrieb: Hi! After I have observed some very subtle and hard-to-reproduce bugs in our app, I found out that Tcl object handling in some places in NS code, although by the book is really a source of trouble. Like: Tcl_SetIntObj(Tcl_GetObjResult(interp), 1); /* Unsafe? */ This construct assumes that object stored in the interp result is not shared. But, when I modify it to look like: Tcl_SetObjResult(interp, Tcl_NewIntObj(1));/* Safe! */ Another option is to use Tcl_ResetResult() * Side effects: *It resets the result object to an unshared empty object. It *then restores the interpreter's string result area to its default *initialized state, freeing up any memory that may have been *allocated. It also clears any error information for the interpreter. When i developed the byte-code support for xotcl, i found some subtle differences on that, depending on byte-code-compiled code or not (this was with some earlier tcl 8.4 versions). Not sure, what's faster, resetResult() + setIntObj() or setObjResult() + newIntObj(). The difference in speed is most likely not significant. however, resetResult allows to append to the object, clears error state, etc. -gustaf