Rails Partial 性能太差

hlxwell · July 13, 2013 · Last by hlxwell replied at July 14, 2013 · 5288 hits

一个列表,加入有 20 行,每行都是用 partial 去渲染,需要用 900 毫秒,但是如果不用 partial,只要 300 毫秒。

还让不让人用了啊。

老实说我觉得在实际页面如果加上和去掉自己平心的感受一次,要是觉得差不多的话,我觉得用也没关系的,不用太纠结了。等到真的感觉到慢的时候再去做优化吧。

我记得 @xdite 似乎有写过一篇 blog 说过 partial 这些,有兴趣可以娶她 blog 看看。

楼上错别字大亮 anyway,多 cache 一下...

你可以试试这个:https://github.com/n8/multi_fetch_fragments?source=cc

I just implemented this on the staging environment of https://www.biglittlepond.com. The one-line render call for the most recently collected items dropped from ~700 ms to ~50 ms. 25 items per page. This will be going into the production release later this week.

Nathaniel Jones

加 collection 选项也可以快一点:http://ruby-china.org/topics/1040#reply11

适合用 cache digest 做缓存

#3 楼 @blacktulip 能 Cache 跟性能慢 是 2 嘛事。

性能不好。老要做 cache,然后就得话很多时间去管理 cache 了。

http://ruby-china.org/topics/12008?page=1

没贴代码之前我认为代码没写好的可能性更大,partial 我一向正常用,该用就用。

9 Floor has deleted

partial 有时真的比较慢,特别是列表里面,如果要 render 500 次 即使一次 1ms 也 500ms 了

#8 楼 @Rei 代码就是最简单的 Partial 使用,你用跟不用就能差很多,如果在 Partial 里加一点数据库访问逻辑,慢的指数就成倍上升。

这个根本不需要看具体代码。只要你吧要做的事情同样的代码放到 Partial 里,就这两个比较而已。不是绝对性能提高,而是仅仅这两者比较。

#11 楼 @hlxwell 那你继续抱怨吧。

在 partial 里有访问数据库逻辑,必须得慢…

掌握模板引擎核心技术,整个 erubis 的小补丁,编译时就把 render :partial => 内联进来,就一样快了

至于在 partial 中访问数据库,是往往比在 helper 慢一点的,看访问和拼接的顺序了。

helper 往往可以先取数据库内容,然后再开始拼接,partial 往往是先拼接一段,再访问数据库,再拼接 (其实 partial 也可以先取再拼接的,效果就差不多了)

拼接 -> 数据库 -> 拼接 更容易产生 page-fault 也就是 CPU 的 L2 cache 失效 (呃,这里讲的是 CPU cache 而不是页面 cache...) 数据库 -> 拼接 的方式 CPU cache miss 就少一点

另外 rails 在每个 partial 里都会调用一次 eval 以注入局部变量,而 eval 是比较重量级的方法,需要解析 -> 生成 bytecode -> 执行三步走。其实注入局部变量在 ruby 2.0+ 可以用不带 eval 的方式实现的... 所以 nyara 才需要 2.0+

楼上在说 c++ 似的…

erb 的渲染都挺慢。不过通常还是可以忍受的。 rails 的核心成员对这一点也心知肚明,所以搞出了 cache_digest。

#16 楼 @swachian erb 不慢,rails 用的 erubis 速度更快,是 rails 把 layout 和 partial 搞得太花哨才慢的...

#16 楼 @swachian 其实最慢的地方在 ActiveRecord... 自从 tenderlove 给 AR 分层分出了 ActiveModel 和 Arel 后,AR 创建的对象就有点太多了,给 GC 增加了不少鸭梨。最后各种调用的时间都统计算在 render 头上,就造成了 "erb 渲染慢" 的错觉

Rails 在 production 环境和 development 环境中对 partial 的处理不同,看 development 日志得出的结论不一定可靠。参考这篇文章:http://bindle.me/blog/index.php/26/helpers-vs-partials-from-a-performance-perspective

#17 楼 @luikore 确实,不带 layout 的时候确实可以快很多。不过这个难道不是引擎本身,而是 rails 的问题?

我比较推荐使用 cells + cache 的方式来代替。

#20 楼 @swachian rails 有 n 层嵌套 layout 就要把内容的输出拷 n 遍。另外 rails 替换了模板引擎的 buffer class, 使用自己的 buffer class , 也略影响性能...

@hooopo @xdite 难道是个妹子吗? 😍

how cells improve your architecture, cell 可以很好的解决 render 过程中出现的某些性能问题,比如去除 view 中的逻辑判断以及 view 中出现的查询

#24 楼 @leomayleomay 挺好的。如果 rails 默认就支持那就好了。不用利用第三方的东西去解决

#23 楼 @greatghoul xdite 是个女大神,不过不是女神。

@greatghoul 你可以看看台湾的 rubyconf,能找到 @xdite 的录像

#27 楼 @tumayun 去了台湾说不定也能找到女神。

#22 楼 @luikore 你又读源码发现了?能请教一下在哪里能找到那个 buffer class?

You need to Sign in before reply, if you don't have an account, please Sign up first.