在 Ruby 中,如果以后不再需要哈希,那么使用 hash.merge!({...}) 而不是 hash.merge({...}) 更好?

发布于 2024-09-12 17:44:38 字数 666 浏览 10 评论 0原文

这种情况发生在 Ruby on Rails 的视图中,其中存在另一个部分的哈希值。该哈希值大约有 20 个键/值对。

(在 HAML 中)

- if (some_conditon)
  = render :partial => 'some_name', :locals => a_hash.merge({ :extra => true })
- else
  -# a lot more processing, including concatenating the partials and return as json
  - some_var.each do |item| 
    - result_html << (render :partial => 'some_name', :locals => a_hash )
    -# etc
  - response.content_type = "application/json"
  = result_html.to_json

所以问题是,merge 应该写成 merge! 吗?因为以后不再需要它,如果创建一个新的哈希,将花费大量时间来创建这个新的哈希(哈希中有 20 项)。如果进行in-place修改的话,可以利用现有的hash结构,往里面添加一项,这样会快很多吗?

This happens in Ruby on Rails's View, where there is a hash for another partial. This hash has about 20 key/value pairs.

There is (in HAML)

- if (some_conditon)
  = render :partial => 'some_name', :locals => a_hash.merge({ :extra => true })
- else
  -# a lot more processing, including concatenating the partials and return as json
  - some_var.each do |item| 
    - result_html << (render :partial => 'some_name', :locals => a_hash )
    -# etc
  - response.content_type = "application/json"
  = result_html.to_json

So the question is, should the merge be written as merge! instead? Because it is no longer needed later, if a new hash is created, a lot of time will be spent for creating this new hash (20 items in hash). If an in-place modification is done, it can use the existing hash structure and add one item to it, which will be a lot faster?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

幻梦 2024-09-19 17:44:38

这是一个微观优化。与所有此类问题一样,“我应该……吗?”的问题。通过分析并查看是否 A) 相关代码一开始就占用了大量时间,以及 B) 更改是否导致了很大的加速来回答这个问题。如果 A 不是这种情况,则不要继续进行 B。如果 B 不是这种情况,则不值得进行更改,从而使代码变得不太干净。

至于安全考虑,您不仅需要考虑稍后是否要在方法中使用该哈希,还要考虑是否有任何其他对象可能引用该哈希。如果您从另一个对象获取此哈希,并且该对象将其存储在实例变量中,则向哈希添加键将导致另一个对象看到变异版本。

This is a micro-optimization. As with all such matters, the question of "Should I…?" is answered by profiling and seeing whether A) the code in question is taking up a lot of time to begin with, and B) the change results in much of a speedup. If A isn't the case, don't proceed to B. If B isn't the case, the change isn't worth making the code less clean.

As for safety considerations, you don't only have to consider whether you're going to use that hash later in the method, but whether any other objects might have references to the hash. If you got this hash from another object and that object has it stored in an instance variable, adding keys to the hash will cause the other object to see the mutated version.

云淡风轻 2024-09-19 17:44:38

如果您确定修改现有哈希不是问题,那么您当然可以使用 merge!。但是,我不确定它是否会比简单地使用合并快“很多”。复制 20 个左右对象的哈希可能不是一个非常耗时的操作。但是,如果这是一个问题,您可以对不同的实现进行基准测试,看看通过执行其中一种实现方式可以获得多少收益。

If you are certain that modifying the existing hash is not a problem, then you could certainly use merge!. However, I'm not sure if it will be "a lot" faster than simply using merge. copying a hash of 20 or so objects probably isn't an extremely time consuming operation. But, if it is a concern, you could benchmark the different implementations and see how much you will gain by doing one over the other.

和我恋爱吧 2024-09-19 17:44:38

目前该功能可能不需要它,但如果您需要在从现在起的六个月内扩展视图,我不会感到惊讶。六个月后,您可能会非常惊讶地发现 :extra =>; true 填充到此 if/else/end 块之后的哈希中。

所以问问自己,六个月后你会对哪一个感到更惊讶:找到 :extra => true 在你的哈希中,或者没有找到 :extra => true 在你的哈希中。如果没有完整的细节,很难说我更喜欢哪一条,我可以想象这两条路都是有意义的。

我不会担心速度,除非您的分析表明创建新的哈希代表了可测量的处理量。

It might not be needed later in the function at the moment, but I wouldn't be surprised if you need to extend the view in the six months from now. And in six months time, you might be very surprised to find :extra => true stuffed into your hash after this if/else/end block.

So ask yourself which you would be more surprised by, in six months time: finding :extra => true in your hash, or not finding :extra => true in your hash. Without full details, it's hard to say which one I would prefer, I can imagine both paths making sense.

I wouldn't worry about speed unless your profiling has demonstrated that creating a new hash represents a measurable amount of processing.

十六岁半 2024-09-19 17:44:38

如果你担心速度,你可以很容易地测试它,否则使用 merge()

if you're worried about speed you could test this very easily, otherwise use merge()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文