读书人

怎么写出有效率的 Ruby Code

发布时间: 2012-11-03 10:57:43 作者: rapoo

如何写出有效率的 Ruby Code
如何出有效率的 Ruby Code

Ruby 是很慢的言,但有些作法用得,是有不的改善。不要知道程式的可性跟行效率有候是突的,需拿捏,尤其 software life cycle 一始可性比重要。有句最佳化的典名言一定要引一下:

未成年就,是一切邪的根源
Premature optimization is the root of all evil

一些看到有趣的事情,PDF 有更的 example code。


INSTANCE VARIABLES VERSUS ACCESSORS
@attrubute 比 self.attrbute 快(method call 比),如果你不需要 public method 或有 sub-class 的需求,考不要用 attr_accessor 等方式建立 read/write method。

LOCAL VARIABLES ARE CHEAP
method 中的若常用,可以先存成 Local Variables 再多次使用。

INTERPOLATED STRNGES
方法一 s = “:#{a}.#{b}” 比方法二 s = “:” << a.to_s << “.” << b.to_s 快多!! 不需要多用 << method call。另外引跟引有效率上的差。

IN-PLACE UPDATES
直接修改比一份快: gsub! 比 gsub 快,merge! 比 merge 快。例如例 s.gsub().gsub!().gsub! 而不是 s.gsub.gsub.gsub

不要小心,Ruby 於 ! 版本的方法回值有候不是自己(得查 API 定一下),因此法用串接法。

SET VERSUS ARRAY
如果你只用到 Array 的 uniq, |, %, 等群集操作,考改用 Set 比快,像是 include? 就可以在 O(1) 做完。而 Hash 又比 Array 。

MAKE DECISIONS AT LOAD TIME
注意到在 module 或 class 的 definition scope 也是可以行程式的,而且只有第一次 require source code 行一次。

class Foo
if C=’somesetting’
def A
…version 1
end
else
def A
…version 2
end
end
end

SELF-MODIFYING CODE
避免出自己修改自己定的程式(也不好code吧),改用 singleton 方式做 alias_method 跟 remove_method。

TEST MOST FREQUENT CASE FIRST
用 case 把常生的放前面,若都差不多,把的操作的放後面。

OPTIMIZE ACCESS TO GLOBAL CONSTANTS
在 Constant 前面加上 namespace operator :: 比快,少查

CACHING DATA IN INSTANCE VARIABLES
例如在 controller 面 def captial_letters { (“A”..”Z”).to_a } end 改用 def captial_letters { @captial_letters ||= (“A”..”Z”).to_a } end

CACHING DATA IN CLASS VARIABLES
承上,如果 data 大又持存在,可以改用 @@capital_letter = (“A”..”Z”).to_a 然後定 def captial_letters { @@captial_letters } end。在 ActiveRecord 中也可以先把 DB 的料出作 CONSTANTS,就不需要每次都查料了:

class State < ActiveRecord::Base
NAMES_ABBR = self.find(:all).map do { |s| [s.name,s.abbr] }
end

CODING VARIABLE CACHING EFFICIENTLY
用 @var ||= begin …expr… end 而不是 @var = begin …expr… end unless @var,只需查 @var 一次。但如果 @var要能吃 nil 或 false 就只能多一 boolean 忙了。

INITIALIZING VARIABLES WITH NIL
若有值,就不需要初始成nil

USING .NIL?
如果要的值已知不是 Boolean,那就不需要用 .nil 多一 method call,直接 if x 就好了而不是 if x.nil?

NIL? OR EMPTY? VERSUS BLANK?
ActionPack 有提供 x.blank?,不需要用 x.nil? || x.empty?

USING RETURN
然 Ruby 很明自回最後算的值,但明 return 比快 (Ruby 1.9有改善)

USING ANY?
用 empty? string, array or hash 而不要用 any?,速度差倍 (而且 Ruby 1.9 也拿掉 any?method了)

BLOCK LOCAL VARIABLES
在 Ruby 1.8 面,在 Block 面存取 Block 外面的 local variable 竟然比面的 local variable 快!! 不 Ruby 1.9 修正奇怪的事就是了。

PARALLEL ASSIGNMENTS
很方便,但 a,b=1,2 算出 Array [1,2] 是垃圾。(Ruby 1.9 修正了,改 true)

DATE FORMATTING
用 parse_date 把 String 成 Date 是非常昂的操作,建你直接用字串操作(正表示法)把 String(例如DB出的db_date) 成你想要的格式,或是中拆出你想要的年月日。(PDF 有 example code)

TEMPORARY DATA STRUCTURE CONSTANTS
如果用到一的料(如Array)但接下不更改,可以改用 Constant 宣告,避免。

OBJECTSPACE.EACH_OBJECT
DO NOT USE IT,你不想在 per-request 下去行的,很。

UNNECESSARY BLOCK PARAMETERS
def foo(bar, &block) 的 &block 若在函式不需要用到(可以直接用 yield 使用的),不要加。成 Proc 比 yield 的慢5倍!!

SYMBOL.TO_PROC
ActiveSupport 提供的 @var.map(&:name) 法,然方便,但是用 inline block 的方法 @var.map{ |a| a.name| } 行效率比快。

REQUIRING FILES DYNAMICALLY
在 Rails 中若碰到一未定的常,它自去 load source files 入定。了避免混淆 file-loading 制,不需 require ‘client’ (又是另一套 auto-loaded 制),只要一行 Client 就好了。

INCLUDING MODULES VERSUS OPENING CLASSES
使用 module mix-in 比打 class 加入 method 慢一些,如果你的 module 只一 class 做 mix-in,那不如直接打加入 methods 就好了。

读书人网 >Ruby Rails

热点推荐