`
yapex
  • 浏览: 7454 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

Ruby Meta Programming: define_method or class_eval

阅读更多
今天刚巧看到Matt Aimonetti的blog上讨论ruby meta programming的执行效率问题,就跟着做了一下,还是学到了不少东西。大致说一下吧,首先Matt写了一个简单的计算时间的DSL类:
module TimeDSL
    def second
      self * 1
    end
    alias_method :seconds, :second

    def minute
      self * 60
    end
    alias_method :minutes, :minute

    def hour
      self * 3600
    end
    alias_method :hours, :hour

    def day
      self * 86400
    end
    alias_method :days, :day

    def week
      self * 604800
    end
    alias_method :weeks, :week

    def month
      self * 2592000
    end
    alias_method :months, :month

    def year
      self * 31471200
    end
    alias_method :years, :year
end
Numeric.send :include, TimeDSL


这个类很简单,就是为Numeric类增加了与时间相关的一些方法,这样就可以使用类似的代码计算时间了,例如:
1.hours + 20.minutes # => 一小时20分钟是多少秒
3.days + 5.hours # => 3天零5小时
2.years + 10.months # => 两年十个月


代码很简单,不过请大家注意Matt使用
Numeric.send :include, TimeDSL
方法为Numeric类增加了TimeDSL这个模块。
然后他又写了一个利用define_method方式实现TimeDSL的类(为了方便说明,我略作了修改)
module BadMetaTimeDSL

    {:second => 1, 
     :minute => 60, 
     :hour => 3600, 
     :day => [24,:hours], 
     :week => [7,:days], 
     :month => [30,:days], 
     :year => [364.25, :days]}.each do |meth, amount|
		define_method "b_#{meth}" do
			amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount
			self * amount
		end
		alias_method "b_#{meth}s".intern, "b_#{meth}"
    end
  end
Numeric.send :include, BadMetaTimeDSL


他发布了这两个类benchmark的测试数据,并得出结论说ruby的meta programming基本上要比正常方式慢3倍左右(我自己的测试数据是2倍左右)
这个结论很快就引来了很多人的的讨论,最后Wycats提出了改进方案
module GoodMetaTimeDSL
  SECOND  = 1
  MINUTE  = SECOND * 60
  HOUR    = MINUTE * 60
  DAY     = HOUR * 24
  WEEK    = DAY * 7
  MONTH   = DAY * 30
  YEAR    = DAY * 364.25

  %w[SECOND MINUTE HOUR DAY WEEK MONTH YEAR].each do |const_name|
      meth = const_name.downcase
      class_eval <<-RUBY
        def g_#{meth}
          self * #{const_name}
        end
        alias g_#{meth}s g_#{meth}
      RUBY
  end
end
Numeric.send :include, GoodMetaTimeDSL

新的类执行效率直逼正常方式定义的类,可以说基本上没有太大的差异了。究其原因define_method需要创建Proc才能执行,而class_eval和ruby自身执行方式没有什么差别,都是直接解释执行。

最后的结论是:如果可能,尽量使用class_eval进行meta programming

不知道怎么把附件的图贴进来,大家看附件吧,也包括源代码。
整个测试都在jruby 1.1.3下通过

可以参考http://railsontherun.com/2008/6/18/about-metaprogramming-speed
  • 大小: 21.5 KB
  • time_dsl_benchmark.rar (943 Bytes)
  • 描述: 需要安装rBench进行测试 gem install rbench
  • 下载次数: 5
14
6
分享到:
评论
2 楼 yang_kunlun 2008-11-12  
    [img][/img]

    [*]

    [*]
引用
[u][/u]
1 楼 sunfengcheng 2008-07-29  
[url][
  1. module BadMetaTimeDSL  
  2.  
        {:second => 1,   
         :minute => 60,   
         :hour => 3600,   
         :day => [24,:hours],   
         :week => [7,:days],   
         :month => [30,:days],   
         :year => [364.25, :days]}.each do |meth, amount|  
            define_method "b_#{meth}" do 
                amount = amount.is_a?(Array) ? amount[0].send(amount[1]) : amount  
                self * amount  
            end 
            alias_method "b_#{meth}s".intern, "b_#{meth}" 
        end 
      end 
    Numeric.send :include, BadMetaTimeDSL
/url]

相关推荐

    Define_Grid_Motion.zip_DEFINE_GRID_MOTION_fluent udf_fluent变形_f

    标题中的"Define_Grid_Motion.zip_DEFINE_GRID_MOTION_fluent udf_fluent变形_f" 提到了`Fluent`中的`Define Grid Motion`功能,这正是用来定义网格运动的一种方法,它允许用户自定义边界条件下的网格动态行为。...

    DEFINE_DPM_EROSION.rar_DEFINE DPM EROSION_DPM_UDF EROSION_fluent

    标题中的"DEFINE_DPM_EROSION.rar_DEFINE DPM EROSION_DPM_UDF EROSION_fluent"指的是一款与 Fluent 模拟软件相关的用户定义函数(UDF),用于模拟颗粒动力学(DPM)过程中的侵蚀现象。Fluent 是一款广泛使用的计算...

    VIVUDF2_CG_MOTION_DEFINE_CG_MOTION_二维运动动网格_

    标题 "VIVUDF2_CG_MOTION_DEFINE_CG_MOTION_二维运动动网格_" 提供的信息表明,这个主题涉及到使用Fluent软件进行流体动力学(CFD)模拟时,利用CG_MOTION功能来定义二维物体的动态运动。描述中的 "fluent DEFINE_CG...

    patch_def_ruby_Metaprogramming_Before_

    在Ruby中,元编程的一个常见工具是`Module#define_method`,它可以让我们在运行时动态地定义方法。然而,如果我们要实现`def_before`这样的功能,我们需要创建一个可以拦截并控制方法调用的机制。下面我们将深入探讨...

    UDF控制柔性振动膜的动网格问题.zip_GRID udf_define grid motion_define_cg_动网格_动

    动网格,DEFINE_CG_MOTION,DEFINE_GRID_MOTION,很好的模板

    ruby metaprograming

    instance.singleton_class.class_eval do def unique_method puts "This is a unique method." end end instance.unique_method # 输出: "This is a unique method." ``` ##### 2. 开放类(Open Classes) 在...

    Ruby元编程基础学习笔记整理

    Ruby支持动态定义方法的能力,这可以通过`define_method`方法实现。 ##### 示例代码分析 ```ruby class MyClass define_method :my_method do |args| args * 3 end end obj = MyClass.new puts obj.my_method...

    MetaProgramming-Play:重写 Ruby 注入方法以了解元编程

    使用define_method创建Ruby 内置attr_accessor方法的布尔版本。代码片段: 使用define_method attr_accessor方法 def self . attr_accessor? ( attr ) read_method = " #{ attr } ?" write_method = " #{ attr } =...

    第四章 DEFINE宏_UDf宏_UDFdescription_

    "第四章 DEFINE宏_UDf宏_UDFdescription_"这一标题暗示了我们将会探讨Fluent中的用户定义函数(User-Defined Functions,简称UDFs)以及与其相关的DEFINE宏。在Fluent中,UDFs允许用户自定义物理模型,以处理标准...

    Meta Programming Ruby

    ### Meta Programming Ruby:深入理解Ruby元编程 #### 核心概念与原理 《Meta Programming Ruby》这本书由Paolo Perrotta编写,旨在帮助读者深入了解Ruby语言的元编程特性及其强大功能。通过本书的学习,读者可以...

    UDF 动网格,DEFINE-CG-MOTION,DEFINE-GRID-MOTION

    `DEFINE_CG_MOTION`和`DEFINE_GRID_MOTION`是UDF编程中用于定义网格运动的两个关键函数。它们是ANSYS Fluent内建的宏,用于在UDF中指定网格如何随时间变化。 1. `DEFINE_CG_MOTION`:这个宏主要用于定义中心点...

    usbip_windows_v0.2.0.0_signed金品迪修正版openwrt

    #define USBIP_VERSION 0x000111 //将0x000106改为0x000111重新编译即可运行。不再出现如下错误。 usbip err: usbip_network.c: 119 (usbip_recv_op_common) recv op_common, -1 usbip err: vhci_attach.c: 202 ...

    Superfast:最快的:rocket:,非常易于使用的:face_with_open_mouth:,以及用于PHP的免费:grinning_face_with_smiling_eyes:API构建框架

    超快框架最快的 :rocket: ,非常好用 :face_with_open_mouth: ,并免费 :grinning_face_with_smiling_eyes: PHP的API构建框架档案结构index....define ( "DEBUG_MODE" ,

    ruby_1_9_3_core_rdocs.gz

    8. **元编程**:Ruby的元编程能力是其一大特色,通过`class_eval`、`instance_eval`和`define_method`等方法,可以在运行时动态修改类和对象的行为。 9. **线程与并发**:Ruby 1.9.3引入了全局解释器锁(GIL),...

    Ruby元编程之梦中情人method_missing方法详解

    总的来说,理解何时和如何使用`method_missing`和`define_method`是掌握Ruby元编程的关键。`method_missing`提供了一种强大的灵活性,但其代价是性能和可读性,而`define_method`则在保持代码整洁的同时提供了动态...

    label_break_ruby_Metaprogramming_

    在Ruby编程语言中,元编程(Metaprogramming)是一种强大的特性,允许程序在运行时检查、修改甚至创建自身的结构和行为。元编程能够增加代码的灵活性和可扩展性,但同时也需要谨慎使用,以避免过度复杂化和降低代码...

    错误Amr文件修复

    * Method: convert_mp3_mehtod * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_cn_com_util_Jni_convert_1mp3_1mehtod (JNIEnv *env, jobject jot, jstring _path); ...

    Ruby-Programming:Ruby基础学习

    例如,`send`方法可以动态调用方法,`define_method`可以在运行时定义方法。 10. **异步编程** Ruby 2.6及更高版本引入了` Concurrent::Promise `库,支持异步编程,允许并行执行任务。 在"Ruby-Programming-main...

    intro_to_metaprogramming:Ruby元编程简介

    使用send , define_method和method_missing遍历不同的元编程技术 将您的思维扩展到元编程,并让您考虑可以在自己的代码中利用它的地方 设置 要求 该讲习班是使用Ruby 1.9.3创建的,但是在2.1.2版本中有效。 假设您...

Global site tag (gtag.js) - Google Analytics