Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most efficient operator to compare any two items?

Frequently I need to convert data from one type to another and then compare them. Some operators will convert to specific types first and this conversion may cause loss of efficiency. For instance, I may have

my $a, $b = 0, "foo"; # initial value
$a = (3,4,5).Set;     # re-assign value
$b = open "dataFile"; # re-assign value

if $a eq $b { say "okay"; } # convert to string
if $a == 5 { say "yes"; }   # convert to number
if $a == $b {} # error, Cannot resolve caller Numeric(IO::Handle:D: );

The operators "eq" and "==" will convert data to the digestible types first and may slow things down. Will the operators "eqv" and "===" skip converting data types and be more efficient if data to be compared cannot be known in advance (i.e., you absolutely have no clue what you are going to get in advance)?

like image 872
lisprogtor Avatar asked Dec 06 '22 08:12

lisprogtor


1 Answers

It's not quite clear to me from the question if you actually want the conversions to happen or not.

Operators like == and eq are really calls to multi subs with names like infix:<==>, and there are many candidates. For example, there's one for (Int, Int), which is selected if we're comparing two Ints. In that case, it knows that it doesn't need to coerce, and will just do the integer comparison.

The eqv and === operators will not coerce; the first thing they do is to check that the values have the same type, and if they don't, they go no further. Make sure to use the correct one depending of if you want snapshot semantics (eqv) or reference semantics (===). Note that the types really must be the exact same, so 1e0 === 1 will not come out true because the one value is a Num and the other an Int.

The auto-coercion behavior of operators like == and eq can be really handy, but from a performance angle it can also be a trap. They coerce, use the result of the coercion for the comparison, and then throw it away. Repeatedly doing comparisons can thus repeatedly trigger coercions. If you have that situation, it makes sense to split the work into two phases: first "parse" the incoming data into the appropriate data types, and then go ahead and do the comparisons.

Finally, in any discussion on efficiency, it's worth noting that the runtime optimizer is good at lifting out duplicate type checks. Thus while in principle, if you read the built-ins source, == might seem cheaper in the case it gets two things have the same type because it isn't enforcing they are precisely the same type, in reality that extra check will get optimized out for === anyway.

like image 161
Jonathan Worthington Avatar answered Jan 20 '23 13:01

Jonathan Worthington