【发布时间】:2018-07-03 13:11:09
【问题描述】:
我在这里遇到了一个非常常见的重构情况,在浏览了几篇博客之后,我仍然没有得到任何满意的评论;所以在这里问一个问题。
h = {
a: 'a',
b: 'b'
}
new_hash = {}
new_hash[:a] = h[:a].upcase if h[:a].present?
据我朋友说,这段代码可以通过以下方式重构以提高性能。
a = h[:a]
new_hash[:a] = a.upcase if a.present?
乍一看,它看起来有点优化。但它会产生很大的不同还是过度优化?应该首选哪种风格?
寻求专家建议:)
更新Benchmark n = 1000
user system total real
hash lookup 0.000000 0.000000 0.000000 ( 0.000014)
new var 0.000000 0.000000 0.000000 ( 0.000005)
AND op 0.000000 0.000000 0.000000 ( 0.000018)
try 0.000000 0.000000 0.000000 ( 0.000046)
更新 Memory Benchmark 使用 gem benchmark-memory
Calculating -------------------------------------
hash lookup 40.000 memsize ( 40.000 retained)
1.000 objects ( 1.000 retained)
1.000 strings ( 1.000 retained)
new var 0.000 memsize ( 0.000 retained)
0.000 objects ( 0.000 retained)
0.000 strings ( 0.000 retained)
AND op 40.000 memsize ( 40.000 retained)
1.000 objects ( 1.000 retained)
1.000 strings ( 1.000 retained)
try 200.000 memsize ( 40.000 retained)
5.000 objects ( 1.000 retained)
1.000 strings ( 1.000 retained)
【问题讨论】:
-
取决于您打算做什么。更多的上下文肯定会有所帮助。如果你对 mutating
h没问题,你可以做h[:a] && h[:a].upcase!或h[:a].try(:upcase!) -
要使用第二种方法回答您关于性能和优化的问题,最好围绕它进行一些基准测试。您正在通过存储在变量中来补偿哈希查找。
-
@kiddorails
upcase!或upcase两者都会做同样的事情,因为无论如何我都会使用另一个哈希来存储它的值。还尝试使用try方法进行基准测试。 -
他们不会做与
upcase!相同的事情,可能会改变h中的值,也可能会返回nil。例如'A'.upcase! #=> nil@kiddorails 的观点是new_hash如果更改h[:a]并通过关联h直接是可接受的解决方案,则不需要。这种方式在技术上会更加高效,尽管它是无限小的。 -
@engineersmnky
new_hash对我来说很重要。
标签: ruby performance optimization refactoring ruby-hash