通过添加一些 gems 来提升 Rails 应用的性能 已翻译 100%

oschina 投递于 2014/07/03 06:30 (共 5 段, 翻译完成于 07-03)
阅读 2337
收藏 36
3
加载中

使用Rails一段时间之后,你可能就会开始吹毛求疵的想要提高它性能。这是一系列文章中第一次考虑如何提高(即使微不足道的)Rails的性能。

我将会关注在一些gem的提速上面,在某些情况下,可能是一小部分的Rails,如html转义,String.blank?和JSON工具类。

基准原则

原则,对于仅仅在控制台wrk运行几次来讲,是一个与其过强的词语,但是我这里不是来寻找“圣杯”的,而是提供一些初始的想法。

我将从旧的apache ab切换到wrk

wrk是现代的 HTTP 基准工具,当在一个单一的多核 CPU 上运行时,能够产生巨大的负载。
wrk -t10 -c10 -d10s http://localhost:3000

这条指令运行基准问题10s,使用10个线程,并且保持打开50个HTTP链接,也就是说,这样就足够了。记得将这些基准测试在你实际的应用中跑一下,看一下实际上的性能提高有多少。

0x0bject
翻译于 2014/07/03 09:29
1

escape_utils gem

通过可爱的escape_utils gem可以加快HTML的转义。为了使其能够在Rails中使用,需要添加一个初始值设定来解决:

begin
  require 'escape_utils/html/rack' # to patch Rack::Utils
  require 'escape_utils/html/erb' # to patch ERB::Util
  require 'escape_utils/html/cgi' # to patch CGI
  require 'escape_utils/html/haml' # to patch Haml::Helpers
rescue LoadError
  Rails.logger.info 'Escape_utils is not in the gemfile'
end

对该逻辑进行测试的用例:

def escape_utils
  @escape_me = <<-HTML
    <body class="application articles_show">
      <!-- Responsive navigation
      ==================================================== -->
      <div class="container">
        <nav id="nav">
      <ul>
        <li><a href="/"><i class="ss-standard ss-home"></i>home</a></li>
        <li><a href="/home/about"><i class="ss-standard ss-info"></i>about</a></li>
        <li><a href="/contact"><i class="ss-standard ss-ellipsischat"></i>contact</a></li>
        <li><a href="/home/projects"><i class="ss-standard ss-fork"></i>projects</a></li>
        <li><a href="/tags"><i class="ss-standard ss-tag"></i>tags</a></li>
        <li><a href="/articles?query=code"><i class="ss-standard ss-search"></i>search</a></li>
      </ul>
    </nav>
    <a href="#" class="ss-standard ss-list" id="nav-toggle" aria-hidden="true"></a>
  HTML

  render inline: "Hello  world <%= @escape_me %>"
end

使用标准Rails:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    35.40ms    3.55ms  64.70ms   91.98%
    Req/Sec   142.19     11.68   164.00     83.12%
  2837 requests in 10.00s, 4.92MB read
Requests/sec:    283.61
Transfer/sec:    503.34KB

使用escape_utils gem:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    34.06ms    3.89ms  63.92ms   89.10%
    Req/Sec   148.65     13.36   180.00     75.94%
  2960 requests in 10.00s, 5.46MB read
Requests/sec:    295.98
Transfer/sec:    558.72KB
0x0bject
翻译于 2014/07/03 08:56
1

fast_blank gem

是否在印象里,blank?方法太慢?不用多说,试一下fast_blank gem!

仅需要在你的Gemfile中添加gem 'fast_blank',这应该就可以非常漂亮的提高像这篇文章中提到的String.black?方法的速度。为了测试,我仅添加下俩代码:

fast_blank是一个简单的扩展,提供了一个支持String.blank?功能的快速实现。
 def fast_blank_test
    n = 1000

    strings = [
      "",
      "\r\n\r\n  ",
      "this is a test",
      "   this is a longer test",
      "   this is a longer test
      this is a longer test
      this is a longer test
      this is a longer test
      this is a longer test"
    ]

    Benchmark.bmbm  do |x|
      strings.each do |s|
        x.report("Fast Blank #{s.length}    :") do
          n.times { s.blank? }
        end
      end
    end

    render nothing: true
  end

使用标准Rails:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.40s   207.72ms   1.58s    92.68%
    Req/Sec     3.10      2.11     6.00     53.66%
  69 requests in 10.01s, 33.08KB read
Requests/sec:      6.90
Transfer/sec:      3.31KB

使用fast_blank gem:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.33s   179.56ms   1.41s    93.33%
    Req/Sec     3.07      0.80     4.00     40.00%
  72 requests in 10.00s, 34.52KB read
Requests/sec:      7.20
Transfer/sec:      3.45KB
0x0bject
翻译于 2014/07/03 09:03
1

oj gem

# oj gem
gem 'oj'
gem 'oj_mimic_json' # we need this for Rails 4.1.x

这个测试用例非常简单,仅仅将所有的article序列化为JSON格式:

class SidechannelsController < ApplicationController
  def oj
    render json: Article.all
  end
end

使用标准Rails序列化器:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   108.37ms    5.12ms 134.90ms   83.33%
    Req/Sec    45.76      3.60    55.00     57.69%
  922 requests in 10.00s, 57.41MB read
Requests/sec:     92.17
Transfer/sec:      5.74MB

使用oj gem:

Running 10s test @ http://localhost:3000/sidechannels/bench
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    78.06ms    4.43ms  92.83ms   81.31%
    Req/Sec    63.64      5.33    71.00     64.49%
  1277 requests in 10.00s, 79.83MB read
Requests/sec:    127.65
Transfer/sec:      7.98MB

使用jemalloc

好吧,这其实不是一个真正的gem,如果你想深入探究它,可以看我的这篇文章。在初始测试时,jemalloc并没有产生太多性能的提升,至少对我使用的测试用例是这样的。

提示:某些情况下,可能会默认包含在Ruby中。

更新:请一定尝试一下kzk的jemalloc gem

gem install jemalloc

je -v rails s

深入探究你的Rails应用

不要担心,去用一下Sam Saffron的带有非常棒的FlameGraphsMiniProfiler吧!

0x0bject
翻译于 2014/07/03 09:11
1

结语

鉴于你的应用要做什么,你可能想为你的Gemfile添加上述的一些gem。通常我会把他们都添加上,当然是出于一个好的估量(你可能会想检查你的RAM利用率,然后在添加之前,进行一个完整的测试)。

oj gem基于JSON API,对Rails来说是非常不错的,使用oj gem,你可以删除视图并仅使用代言人或者你选择的模式进行序列化。

0x0bject
翻译于 2014/07/03 09:17
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(15)

小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释

引用来自“小石像怪”的评论

DJm
:w
小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释

引用来自“小石像怪”的评论

DJm
:w
小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释

引用来自“小石像怪”的评论

DJm
W1
小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释

引用来自“小石像怪”的评论

DJm
wW1
小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释
DJm
小石像怪
小石像怪

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。

引用来自“鱼说还休”的评论

可读性,开发高效性和维护性高于性能,爱ruby不解释
DJm
小石像怪
小石像怪

引用来自“朱尚述”的评论

这玩儿在中国用的不多呀!!!
iPad mini 2 16GB版的售价调低至2198元,32GB版售价2588元,4G蜂窝网络版售价分别为3088元和3488元。
鱼说还休
鱼说还休

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?

引用来自“Zoker”的评论

我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。
可读性,开发高效性和维护性高于性能,爱ruby不解释
无所谓了
无所谓了
这玩儿在中国用的不多呀!!!
Zoker
Zoker

引用来自“zjtxqjj”的评论

Ruby的性能比PHP好吧,就是太笨重了

引用来自“Zoker”的评论

感觉上是挺笨重,但是比php方便。

引用来自“Neo”的评论

ruby比php快?这不科学,不是php,python,ruby里面最快就是php吗?
我是说方便…我从来都不去讲语言的快慢,因为我认为如果不深入,再好的语言也写不出高效的程序。
返回顶部
顶部