in reply to scalar reference and length

It's the
my $s = shift;
that copies the string. If you just use $_[0] in the sub, no copying happens. Moreover, recent perl versions have the "copy on write", which means the copy isn't created until it's needed because it becomes different to the original.

Try running your script with kind of a memory monitoring tool. I just used "Resource monitoring" in my LXDE Panel. Clearly, using shift with some modification of the string consumed twice as more memory.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]