比较任何两个项目的最有效运算符是什么?

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

我经常需要将数据从一种类型转换为另一种类型,然后进行比较。一些运算符会先转换为特定类型,这种转换可能会导致效率损失。例如,我可能有

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: );

运算符 "eq" 和“==”将首先将数据转换为可消化的类型,这可能会减慢速度。如果无法提前知道要比较的数据(即,您完全不知道要提前获得什么),运算符 "eqv" 和“===”是否会跳过转换数据类型并提高效率?

===eqv都是先检查操作数是否是同一类型,如果不一样就会returnFalse。所以在那个阶段,他们之间并没有真正的区别。

a === b 运算符实际上是 a.WHICH eq b.WHICH 的缩写。所以它会在操作数上调用 .WHICH 方法,如果操作数非常大 Buf.

,这可能会很昂贵

a eqv b运算符比较复杂,因为它有很多对象比较的特殊情况,所以一般来说你不能说太多。

换句话说:YMMV。如果您真的对性能感兴趣,请进行基准测试!如果另一种解决问题的方法证明性能更高,请准备好调整您的代码。

我不太清楚你是否真的想要转换发生。

==eq这样的操作符实际上是调用multisub这样名字像infix:<==>的,而且有很多候选。例如,(Int, Int) 有一个,如果我们比较两个 Int,就会选择它。在那种情况下,它知道它不需要强制转换,只会进行整数比较。

eqv=== 运算符不会强制转换;他们做的第一件事是检查这些值是否具有相同的类型,如果不相同,他们就不再继续。确保使用正确的语义,具体取决于您是需要快照语义 (eqv) 还是引用语义 (===)。请注意,类型确实必须 相同,因此 1e0 === 1 不会出现,因为一个值是 Num 而另一个是 Int.

==eq 等运算符的自动强制转换行为非常方便,但从性能角度来看,它也可能是一个陷阱。他们胁迫,用胁迫的结果进行比较,然后扔掉。因此,反复进行比较可以反复触发强制。如果您遇到这种情况,将工作分为两个阶段是有意义的:首先 "parse" 将传入数据转换为适当的数据类型,然后继续进行比较。

最后,在任何关于效率的讨论中,值得注意的是运行时优化器擅长取消重复类型检查。因此,虽然原则上,如果您阅读内置源代码,== 可能看起来更便宜,因为它得到两个具有相同类型的东西,因为它没有强制执行它们 精确地 相同的类型,实际上额外的检查将得到优化 === 无论如何。