我有一个
ruby方法需要检查块是否传递给它.
一位同事建议只检查是否有block.nil?性能略快,适用于命名块.这已经非常烦人,因为他正在使用命名块并使用block.call调用它而不是已经显示为 significantly faster的yield,因为命名块在可读性方面更容易理解.
一位同事建议只检查是否有block.nil?性能略快,适用于命名块.这已经非常烦人,因为他正在使用命名块并使用block.call调用它而不是已经显示为 significantly faster的yield,因为命名块在可读性方面更容易理解.
版本1:@H_502_4@
def named_block &block if block.nil? puts "No block" else block.call end end
版本2:@H_502_4@
def named_block &block if !block_given? puts "No block" else block.call end end
基准测试显示版本1比版本2略快,但快速查看source code似乎表明block_given?是线程安全的.@H_502_4@
解决方法
首先,虽然一个零?检查可能比block_given更快?,捕获块很慢.因此,除非您要捕获它,否则性能参数无效.
其次,它更容易理解.每当你看到block_given?时,你就知道究竟是什么了.当你有x.nil?时,你必须停下来想想x是什么.@H_502_4@
第三,这是一个习语.根据我的经验,绝大多数Ruby开发人员更喜欢block_given?.在罗马的时候…@H_502_4@
最后,您可以保持一致.如果你总是使用block_given?问题解决了.如果你使用nil?检查,你必须捕获块.@H_502_4@
>存在性能开销.>它更冗长,是Rubyists试图避免的.>命名事物是编程中最困难的事情之一. :)你能想到一个好名字块Enumerable #map会得到例如吗?>“Grepability”是代码库的理想特征.如果你想找到你检查是否有块的所有地方,那么做什么?检查可能很难.@H_502_4@