4.13.3. Discussion
Lacking (until recently) a built-in mechanism to do this, we must
write our own code to go through the list and test each element. We
use foreach and for, and call
last to ensure that we stop as soon as we find a
match. Before we use last to stop looking, though,
we save the value or index.
A common approach is to try to use grep here. But
grep always tests all elements and finds all
matches, so it's inefficient if you want only the first match.
However, grep might still be faster. That's
because there will be less source code if you use
grep rather than writing your own loop. That means
fewer internal Perl operations, and it is these that in practice
often dominate runtimes.
Beyond a certain size of your data set, a loop that terminates early
will still be faster—assuming it has the chance to do so.
Empirical evidence suggests that for will be
faster as long as you can exit before the first two-thirds of the
list has been examined. It's worthwhile to know how to do that.
Here's an example. Assume that @all_emps holds a
list of Employee objects, sorted in descending order by salary. We
wish to find the highest paid engineer, who will be the first
engineer in the array. We only want to print the engineer's name, so
we want the value, not the index.
When we're searching and want only the index, we can save some code
by remembering that $i will not be an acceptable
array index if we don't find a match. This mainly saves us code
space, as not doing an assignment doesn't really win much compared to
the time spent testing list elements. It's more obscure, because it
tests if ($i < @ARRAY) to check whether we
found a match, instead of the more obvious defined
test in the previous solution.