For Programmers: Free Programming Magazines  


Home > Archive > Tcl > June 2005 > Query about 'shimmering' article on the wiki









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Query about 'shimmering' article on the wiki
rst

2005-06-09, 4:00 pm

Greetings,
I'm having some difficulty understanding the last example
in the wiki article on 'shimmering':

(my comments are prefixed with "# --")

<quote from wiki article on "shimmering">
....
# -- understood and snipped intro & 3 examples
All conversions in tcl currently go through the string
representation. Consider:

set i [expr {$n+1}]
puts [llength $i]

Here, "i" will be an int first, which then needs to be
turned into a list. To do so, a string is constructed,
parsed, and converted to a one-item list.

Which we know is doing too much - an int cannot be anything
but a one-item list. This was a contrived case, but now
compare the two below:
# -- ok so far

uplevel 1 [list myproc $arg]
uplevel [list myproc $arg]

Trouble (a bit: only in terms of trying to achieve top
performance).
# -- woops, I'm lost - that was quick!
</quote>

I've looked up the definitions of 'list', 'concat' and
'uplevel' in the docs but the example is a little too
subtle for me.

I hope a kind expert has the time to enlighten me?

Thank you.
-- rst (bob steel)

Andreas Leitgeb

2005-06-09, 4:00 pm

rst <robertsteelmail@yahoo.com.au> wrote:
> Which we know is doing too much - an int cannot be anything
> but a one-item list. This was a contrived case, but now
> compare the two below:
> uplevel 1 [list myproc $arg]
> uplevel [list myproc $arg]


uplevel can accept an optional first argument, that
can be (if given) either a number or a "#"+number.

in the first of these examples that argument is given and the
rest is used as a list without conversion. All is perfect.

In the second case, uplevel gets only one argument, converts
it to a string to determine if it is numeric or "#"+numeric,
and then, as this check failed, the list is already converted
to a string, thus needs to be eval'd, and thus is much less
performant.

This actually hasn't got anything to do with the string-detour
between list and number, because uplevel needs the interims-
stop at string, anyway (for checking for "#"+number).

I have once been hit by this difference, when I uplevel'ed
a really large list. Leaving out the optional argument made
the whole thing crawl like a snail. Adding the "1" then made
it fast.

rst

2005-06-09, 4:00 pm

Thank you very much for the explanation!
-- rst

Michael Schlenker

2005-06-09, 4:00 pm

rst wrote:
> Greetings,
> I'm having some difficulty understanding the last example
> in the wiki article on 'shimmering':
>
> (my comments are prefixed with "# --")
>
> <quote from wiki article on "shimmering">
> ...
> # -- understood and snipped intro & 3 examples
> All conversions in tcl currently go through the string
> representation. Consider:
>
> set i [expr {$n+1}]
> puts [llength $i]
>
> Here, "i" will be an int first, which then needs to be
> turned into a list. To do so, a string is constructed,
> parsed, and converted to a one-item list.
>
> Which we know is doing too much - an int cannot be anything
> but a one-item list. This was a contrived case, but now
> compare the two below:
> # -- ok so far
>
> uplevel 1 [list myproc $arg]
> uplevel [list myproc $arg]
>
> Trouble (a bit: only in terms of trying to achieve top
> performance).
> # -- woops, I'm lost - that was quick!
> </quote>
>
> I've looked up the definitions of 'list', 'concat' and
> 'uplevel' in the docs but the example is a little too
> subtle for me.
>
> I hope a kind expert has the time to enlighten me?


Take a look at the arguments uplevel expects:
1. Level (optional)
2. Script...

So for uplevel 1 [list myproc $arg] you get top performance...
a) 1 is an int, so no shimmering (or just once from string to int)
b) the second argument is a pure list (with no string representation),
so gets the parsing benefits of pure lists on eval and uplevel

But for the second case things are different:

uplevel [list myproc $arg]

Think like the parser:
1. parse the command, substitute [list ....]
2. now we have
uplevel somelist
3. convert somelist to int, to look if it is the level arg... (shimmers
list to string, then fails on conversion to int...)
4. now the list has an internal string rep, you lose the benefits of
pure list optimization in uplevel and eval...

uplevel could probably be more clever here, as it only got a single
argument,
(basically its broken, see this valid case:

% proc 1 {} {puts foo}
% proc uplevel_is_broken {uplevel 1}
% uplevel_is_broken
wrong # args: should be "uplevel ?level? command ?arg ...?"

Hmm, maybe i should report a bug ;-)...

Michael

Neil Madden

2005-06-10, 8:58 pm

Michael Schlenker wrote:
>
> uplevel could probably be more clever here, as it only got a single
> argument,


Yes, it does seem rather pointless attempting to check for a level in
the one argument case. I can't imagine it's a common error case that
needs to be caught (supplying a level but not a script).

> (basically its broken, see this valid case:
>
> % proc 1 {} {puts foo}
> % proc uplevel_is_broken {uplevel 1}


(You didn't cut+paste this, did you? ;)

> % uplevel_is_broken
> wrong # args: should be "uplevel ?level? command ?arg ...?"
>
> Hmm, maybe i should report a bug ;-)...


Not according to the manpage:
"Level cannot be defaulted if the first command argument
starts with a digit or #."

While I can see the need for this in the uplevel arg arg arg... case, in
the one argument case you could probably drop that restriction.

Of course, the simple solution to both problems (and general good
practice) is to always specify a level when calling uplevel.

-- Neil
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com