Perl will use the first argument as a program to execute, find the echo executable along the search path, invoke it directly, and pass the string "Hi" as an argument.
Note that Perl's system( ) is not the same as the standard libcsystem(3) call.
If there is more than one argument to system( ) or exec( ), or the argument is an array with more than one element in it, the arguments are passed directly to the C-level functions. When the argument is a single scalar or an array with only a single scalar in it, it will first be checked to see if it contains any shell metacharacters (e.g., *, ?). If there are any, the Perl interpreter invokes a real shell program (/bin/sh -c on Unix platforms). If there are no shell metacharacters in the argument, it is split into words and passed directly to the C level, which is more efficient.
In other words, only if you do:
system "echo *"
will Perl actually exec( ) a copy of /bin/sh to parse your command, which may incur a slight overhead on certain OSes.
It's especially important to remember to run your code with taint mode enabled when system( ) or exec( ) is called using a single argument. There can be bad consequences if user input gets to the shell without proper laundering first. Taint mode will alert you when such a condition happens.
Perl will try to do the most efficient thing no matter how the arguments are passed, and the additional overhead may be incurred only if you need the shell to expand some metacharacters before doing the actual call.