考虑
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所说的,这种样式非常流行。
根据我的经验:
if
和短路评估之间不应有性能差异。选择应该是纯粹的风格- CCD_ 8和CCD_。只是如果
||
或&&
后面的表达式很长,以至于它不适合一行,则使用if