$ perl -MO=Concise,func -E'my $y; { my $x; sub func { my $z; say $x+$y
++$z }}'
main::func:
9 <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->9
1 <;> nextstate(main 6 -e:1) v:%,us,fea=15 ->2
2 <0> padsv[$z:6,7] vM/LVINTRO ->3
3 <;> nextstate(main 7 -e:1) v:%,us,fea=15 ->4
8 <@> say sK ->9
4 <0> padrange[$x:FAKE:; $y:FAKE:] /range=2 ->5
7 <2> add[t5] sK/2 ->8
5 <2> add[t4] sK/2 ->6
- <0> padsv[$x:FAKE:] s ->-
- <0> padsv[$y:FAKE:] s ->5
6 <0> padsv[$z:6,7] s ->7
-e syntax OK
IIRC: LexPads (Lexical Scratchpads) are kind of a hash-like structure, roughly similar to symbol-tables. Each scope of the sub has a Pad starting with 0 for the inner scope with { '$z' => SCALARREF }. $x is in Pad-1, $y in Pad-2. The Pads are inspected starting with Pad-0 to find the reference. (see PadWalker for more)
So yes there might be some look up overhead involved, but I'd be surprised if the encountered refs weren't cached at first execution.