今天刚巧看到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
分享到:
相关推荐
标题中的"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"指的是一款与 Fluent 模拟软件相关的用户定义函数(UDF),用于模拟颗粒动力学(DPM)过程中的侵蚀现象。Fluent 是一款广泛使用的计算...
标题 "VIVUDF2_CG_MOTION_DEFINE_CG_MOTION_二维运动动网格_" 提供的信息表明,这个主题涉及到使用Fluent软件进行流体动力学(CFD)模拟时,利用CG_MOTION功能来定义二维物体的动态运动。描述中的 "fluent DEFINE_CG...
在Ruby中,元编程的一个常见工具是`Module#define_method`,它可以让我们在运行时动态地定义方法。然而,如果我们要实现`def_before`这样的功能,我们需要创建一个可以拦截并控制方法调用的机制。下面我们将深入探讨...
动网格,DEFINE_CG_MOTION,DEFINE_GRID_MOTION,很好的模板
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支持动态定义方法的能力,这可以通过`define_method`方法实现。 ##### 示例代码分析 ```ruby class MyClass define_method :my_method do |args| args * 3 end end obj = MyClass.new puts obj.my_method...
使用define_method创建Ruby 内置attr_accessor方法的布尔版本。代码片段: 使用define_method attr_accessor方法 def self . attr_accessor? ( attr ) read_method = " #{ attr } ?" write_method = " #{ attr } =...
"第四章 DEFINE宏_UDf宏_UDFdescription_"这一标题暗示了我们将会探讨Fluent中的用户定义函数(User-Defined Functions,简称UDFs)以及与其相关的DEFINE宏。在Fluent中,UDFs允许用户自定义物理模型,以处理标准...
### Meta Programming Ruby:深入理解Ruby元编程 #### 核心概念与原理 《Meta Programming Ruby》这本书由Paolo Perrotta编写,旨在帮助读者深入了解Ruby语言的元编程特性及其强大功能。通过本书的学习,读者可以...
`DEFINE_CG_MOTION`和`DEFINE_GRID_MOTION`是UDF编程中用于定义网格运动的两个关键函数。它们是ANSYS Fluent内建的宏,用于在UDF中指定网格如何随时间变化。 1. `DEFINE_CG_MOTION`:这个宏主要用于定义中心点...
#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 ...
超快框架最快的 :rocket: ,非常好用 :face_with_open_mouth: ,并免费 :grinning_face_with_smiling_eyes: PHP的API构建框架档案结构index....define ( "DEBUG_MODE" ,
8. **元编程**:Ruby的元编程能力是其一大特色,通过`class_eval`、`instance_eval`和`define_method`等方法,可以在运行时动态修改类和对象的行为。 9. **线程与并发**:Ruby 1.9.3引入了全局解释器锁(GIL),...
总的来说,理解何时和如何使用`method_missing`和`define_method`是掌握Ruby元编程的关键。`method_missing`提供了一种强大的灵活性,但其代价是性能和可读性,而`define_method`则在保持代码整洁的同时提供了动态...
在Ruby编程语言中,元编程(Metaprogramming)是一种强大的特性,允许程序在运行时检查、修改甚至创建自身的结构和行为。元编程能够增加代码的灵活性和可扩展性,但同时也需要谨慎使用,以避免过度复杂化和降低代码...
* 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); ...
例如,`send`方法可以动态调用方法,`define_method`可以在运行时定义方法。 10. **异步编程** Ruby 2.6及更高版本引入了` Concurrent::Promise `库,支持异步编程,允许并行执行任务。 在"Ruby-Programming-main...
使用send , define_method和method_missing遍历不同的元编程技术 将您的思维扩展到元编程,并让您考虑可以在自己的代码中利用它的地方 设置 要求 该讲习班是使用Ruby 1.9.3创建的,但是在2.1.2版本中有效。 假设您...