茱莉亚短路了

  • 本文关键字:短路 茱莉亚 julia
  • 更新时间 :
  • 英文 :


考虑

function foo(x)
x isa Bar || throw(ArgumentError("x is not a Int64..."))
dosomething(x)
end

与传统相反

function foo(x)
if !(x isa Bar) 
throw(ArgumentError("x is not a Bar..."))
end
dosomething(x)
end

(功能等价于!(x isa Int64) && ...)随便找几个包,这种条件评估似乎不受欢迎——从表面上看,它似乎很方便,我更喜欢它的风格。

在风格上有共识吗?我知道不鼓励在中使用Unicode,而不是";在";出于可读性/兼容性的考虑,至少根据蓝色风格指南——这是类似的吗?

这是不是表演性差了?从表面上看,这似乎需要大约相同数量的操作。我也看到过这篇帖子,但答案不是很令人满意,甚至忽略了它现在可能已经过时了。

当问自己这样的性能问题时,通常最好通过@code_lowered@code_typed@code_llvm@code_native查看编译后的代码。这些宏中的每一个都进一步解释了编译过程中的一个步骤。

考虑

function x5a(x)
x < 5 && (x=5)
x
end
function x5b(x)
if x < 5
x=5
end
x
end

让我们试试@code_lowered

julia> @code_lowered x5a(3)
CodeInfo(
1 ─      x@_3 = x@_2
│   %2 = x@_3 < 5
└──      goto #3 if not %2
2 ─      x@_3 = 5
└──      goto #3
3 ┄      return x@_3
)
julia> @code_lowered x5b(3)
CodeInfo(
1 ─      x@_3 = x@_2
│   %2 = x@_3 < 5
└──      goto #3 if not %2
2 ─      x@_3 = 5
3 ┄      return x@_3
)

几乎相同——在编译过程中会进一步简化吗?让我们看看!

julia> @code_typed x5a(3)
CodeInfo(
1 ─ %1 = Base.slt_int(x@_2, 5)::Bool
└──      goto #3 if not %1
2 ─      nothing::Nothing
3 ┄ %4 = φ (#2 => 5, #1 => x@_2)::Int64
└──      return %4
) => Int64
julia> @code_typed x5b(3)
CodeInfo(
1 ─ %1 = Base.slt_int(x@_2, 5)::Bool
└──      goto #3 if not %1
2 ─      nothing::Nothing
3 ┄ %4 = φ (#2 => 5, #1 => x@_2)::Int64
└──      return %4
) => Int64

两个函数都有相同的降阶代码,这意味着它们将产生相同的汇编代码,从而执行相同的CPU指令集。

关于样式,官方样式指南中没有记录它,因此代码可读性是标准,就像Bogumil所说的,这种样式非常流行。

根据我的经验:

  1. if和短路评估之间不应有性能差异。选择应该是纯粹的风格
  2. CCD_ 8和CCD_。只是如果||&&后面的表达式很长,以至于它不适合一行,则使用if

最新更新