in reply to Getting the size of the call stack (efficiently)

What's so inefficient about it? The fact that there appears to be a lot of make-work code? I think you'll find that there are already modules available which will do what you want, Devel::StackTrace and Devel::CallerItem spring to mind, but I suspect they call caller under the covers themselves.

You could use them as building blocks, and then there wouldn't be as much visible caller-frame-grovelling code in your own code.

Or you could turn the problem on its head and use Hook::WrapSub to track your caller stack yourself, by writing push and pop wrappers that maintain a stack, around the functions you're interested in tracking.

Apart from that, I'm not surprised you find your code as shown to be slow... it has an infinite loop! update: err, no you're right it hasn't. Nonetheless, C-style for loops are so rare in Perl that I probably won't be the only person who gets confused by it (... I was looking for a last somewhere I guess).

You should I think it would be more readable to recast it as something like:

my $level = 0; while (my @frame = caller($level++)) { # do stuff with the current frame }

update: I didn't realise at first that you only cared about the depth, not what's at each level. In which case, the following snippet will be pretty efficient (since it is blockless):

my $level = 0; 1 while caller(++$level);

I wouldn't worry about it being too slow, and least not right away. Make it readable first.

• another intruder with the mooring in the heart of the Perl

Replies are listed 'Best First'.
Re^2: Getting the size of the call stack (efficiently)
by DrWhy (Chaplain) on Feb 28, 2007 at 01:27 UTC
    Apart from that, I'm not surprised you find your code as shown to be slow... it has an infinite loop! You should recast it as something like: ...
    Um. No? I've played around with my implementation a couple of different ways. I've not yet encountered it failing to terminate with the desired result.
    update: I didn't realise at first that you only cared about the depth, not what's at each level. In which case, the following snippet will be pretty efficient (since it is blockless):
    Ah, yeah that's a little faster, about 15% faster than the version with the block.

    By the way, in benchmarking these two methods I found that getting the stack depth (either way) is really quite fast, I had to do a million repetitions of my test code (each run had a stack depth of 3). That's much less overhead than my naive expectations would have predicted.

    Update: I played around with the two versions a little more and found that really the difference between the block and the inline versions is only about 4%. My block implementation had some extra overhead unrelated to the 'blockiness' of it.

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."