我们都知道在编译Ruby的时候你需要使用configure的 --disable-pthread参数。没错,在configure --disable-pthread 可以让你得到大约 30% 性能提高。但是,这是为什么呢?
所有的这一些我们需要使用 strace 工具,这个工具可以打出所有的真实的操作系统的调用。
下面,是一段我们测试的例程:
def make_thread
Thread.new {
a = []
10_000_000.times {
a << "a"
a.pop
}
}
end
t = make_thread
t1 = make_thread
t.join
t1.join
如果我们使用 strace 工具去测试 configure --enable-pthread 版本的Ruby引擎,那么我们可以得到下面这样的结果:
22:46:16.706136 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
22:46:16.706177 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
22:46:16.706218 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
22:46:16.706259 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000005>
22:46:16.706301 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
22:46:16.706342 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
22:46:16.706383 rt_sigprocmask(SIG_BLOCK, NULL, [], 8 ) = 0 <0.000004>
你会发现上面的sigprocmask 系统调用一页一页又一页地没完没了的。如果你用 strace -c,你会发现一共大约20,054,180 个sigprocmask系统调用。但是,如果你是在--disable-pthread 的Ruby版本下运行,你会发现根本没有那么多的sigprocmask 系统调用(只有 3 次,简直就是天壤之别)
查看一下源代码
我们知道 configure 是一个脚本,其主要用来创建一个 config.h 文件,其中有一大堆宏定义 defines ,这些宏定义决定了使用什么样的函数。所以,让我们来比较一下版本 ./configure --enable-pthread 和版本./configure --disable-pthread的不同之处吧。
$ diff config.h config.h.pthread
> #define _REENTRANT 1
> #define _THREAD_SAFE 1
> #define HAVE_LIBPTHREAD 1
> #define HAVE_NANOSLEEP 1
> #define HAVE_GETCONTEXT 1
> #define HAVE_SETCONTEXT 1
好的,现在我们再 grep 一下Ruby的源代码,我们可以看到只要HAVE_[S/G]ETCONTEXT 被设置了,Ruby 就会调用setcontext() 和getcontext() 这两个系统调用来存取context 的状态,以便异常处理时的切换(通过EXEC_TAG)。
而如果 HAVE_[S/G]ETCONTEXT 没有被定义 的情况下,Ruby 会使用 _setjmp/_longjmp这两个系统调用。
我们来看看 _setjmp/_longjmp 的man page:
… The _longjmp() and _setjmp() functions shall be equivalent to longjmp() and setjmp(), respectively,
with the additional restriction that _longjmp() and _setjmp() shall not manipulate the signal mask…
还有setcontext /getcontext的 man page:
… uc_sigmask is the set of signals blocked in this context (see sigprocmask(2)) …
我们可以看到 getcontext 调用每次都要调用sigprocmask 但是_setjmp 不会。
补丁
通过补丁增加了一个configure 的参数 --disable-ucontext 其可以让你关闭使用 setcontext或getcontext,你只需要像如下方式使用就好了。
./configure --disable-ucontext --enable-pthread
补丁下载:http://github.com/ice799/matzruby/commit/0b9b69f9653782a33aee2b8937d405eae245b60c
如果你以这种方式编译Ruby,那么,你的程序的性能在同等条件下可能会有30%左右的提升。
<!-- 分页 --><!-- 分页end -->
来源:酷壳 责编:豆豆技术应用
分享到:
相关推荐
我们都知道在编译Ruby的时候你需要使用configure的 --disable-pthread参数,而在configure --disable-pthread 可以让你得到大约 30% 性能提高。本文将分析Ruby性能的提高原因并给出更好的建议。
Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试 Ruby性能测试
rubyPHP的高性能体现在以下几个方面: 1.页面缓存。页面缓存指之前加载过的页面以文件方式缓存在服务器中,在一段时间内再次加载相同页面时无需重新执行页面逻辑直接加载静态页面。rubyPHP的页面缓存是自动进行的,...
Skylight - Rails应用程序的智能分析工具能够可视化请求性能
如果已经了解怎么实现页面性能测试,那么本文将带您体会如何用Ruby来实现。为什么选择Ruby来实现,而不是用QTP呢?原因是Ruby有着QTP所无法比拟的优点。
Ruby 方法、类 : Ruby 方法、类 ruby-9-method.mp4 ruby-9-method.mp4
借助基本的数学方法,并使用Ruby和R语言做一些简单的编程工作,你就能学会如何对问题建模,并找出解决方案。 要阅读《R和Ruby数据分析之旅》,对编程有基本了解就足够了。书中会对Ruby和R做一个简明的介绍,之后你...
Functo是ruby中的可组合方法对象
ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码
Ruby On Rails 框架自它提出之日起就受到广泛关注,在“不要重复自己”,“约定优于配置”等思想的指导下,Rails 带给 Web 开发者的是极高的开发效率。 ActiveRecord 的灵活让你再也不用配置繁琐的 Hibernate 即可...
Dalli - 高性能Ruby memcached客户端
Falcon:用于Ruby的高性能web服务器,支持HTTP/2和HTTPS
R和Ruby数据分析之旅 数据分析 数据挖掘
很好的ruby学习材料,ruby的入门有点难,比较繁琐,这本书很好的帮助大家开启ruby的大门
ruby2ruby 提供一些用来根据 RubyParser 兼容的 Sexps 轻松生成纯 Ruby 代码的方法。可在 Ruby 中轻松实现动态语言处理。 标签:ruby2ruby
ruby\笨方法学\笨方法学
ruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ruby DBIruby DBI ruby DBI ...
笨方法学Ruby中文pdf。感兴趣的人可以拿来学习ruby语言。
本人学习总结的ruby on rails 3.1.0数据库类查询方法,比较全了
RuboCop是Ruby静态代码分析器,基于社区Ruby风格指南