`

让Ruby性能增加30%的改进方法分析

 
阅读更多

 我们都知道在编译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 -->

来源:酷壳 责编:豆豆技术应用

分享到:
评论

相关推荐

    ruby2.6.1.zip

    8. **Ruby标准库增强**:Ruby 2.6.1的内置库进行了扩展和更新,例如`matrix`库支持复数运算,`strscan`库改进了性能,`date`库增加了对更多历法的支持等。 9. **更好的错误报告**:Ruby 2.6.1改进了错误报告,提供...

    ruby-1.9.3-p551.tar.gz

    1.9.3是这个版本的一个小迭代,而p551是该版本的一个具体补丁,通常包含错误修复和性能改进。 描述中提到的"MySQL innodb分析"是指针对MySQL数据库系统中InnoDB存储引擎的性能分析。MySQL是一款开源的关系型数据库...

    Ruby-BluepillRuby编写的简单进程监控工具

    8. **可扩展性**:由于是用Ruby编写,Bluepill可以很容易地与其他Ruby库集成,增加更多的功能。 9. **社区支持**:作为开源项目,Bluepill有活跃的开发者社区,不断更新和改进,提供及时的技术支持和更新。 在...

    Ruby-Traceroute一个Rake任务帮助你找到Rails3应用中堵死的路线和未使用的actions

    而“未使用的actions”则指的是控制器中的方法没有被任何路由关联,这些无用的动作可能会增加代码维护的复杂性,同时也浪费了编译和运行时的资源。 “Ruby开发-代码分析和度量”这个标签暗示了Ruby-Traceroute是...

    Ruby-Rails的AB测试

    在Ruby on Rails框架中,A/B测试是一种非常重要的实践,用于评估和优化网站或应用程序的用户体验和性能。A/B测试,也称为分组测试或对照实验,是将用户随机分配到两个或更多版本(变体)的同一产品或功能中,以比较...

    rubyinstaller.zip

    8. **RubyVM统计信息**:Ruby 2.6增加了`RubyVM::InstructionSequence`模块,提供了一些内部VM级别的统计信息,有助于分析性能。 9. **内存管理**:对垃圾回收机制进行了优化,提高了内存管理效率,降低了内存占用...

    rubyinstaller-2.6.1-1-x64--rubyinstaller-2.5.0-2-x64.zip

    Ruby 2.6系列是一个重要的更新,引入了许多新特性和性能改进。其中包括改进的垃圾回收机制,提升了内存管理效率;增加了`yield`关键字的新用法,支持块参数的解构赋值;以及对JIT(Just-In-Time)编译器的优化,提高...

    软件工程实践者的研究方法 (中文版)

    - **再工程**:通过对现有软件系统的重构来改进其结构和性能。 #### 八、结论 《软件工程:实践者的研究方法》第六版全面而深入地探讨了软件工程领域的各个方面,不仅适合计算机相关专业的学生作为教材使用,也...

    Webrick rails外部电脑访问慢

    为了解决Webrick服务器远程访问速度慢的问题,可以通过以下两种方法来提升性能: ##### 第一处修改:减少DNS查询 **文件位置**:`server.rb` **方法**:`GenericServer#start_thread` **原始代码**: ```ruby ...

    java 6 开发必备

    7. **改进的日志API**:Java 6的日志API(java.util.logging)得到了加强,增加了更灵活的日志配置和更好的性能,使得日志记录更加实用。 8. **增强的JDBC**:Java 6的JDBC API增加了对存储过程的改进支持,包括...

    sunnyland.zip

    Ruby2表示这是Ruby的一个特定版本,通常随着语言的更新,版本号也会相应增加,每个新版本可能包含性能改进、新特性和错误修复。 "Ruby2_Data" 文件夹很可能包含了与"Ruby2.exe"相关的资源文件,比如配置文件、库、...

    sonarqube7.7.rar

    7. **多语言支持**:SonarQube支持多种编程语言,7.7版本可能增加了对新语言的支持,或者增强了对现有语言的分析能力,例如Python、Ruby等。 8. **插件更新**:SonarQube生态系统中的插件也随着7.7版本进行了更新,...

    DicomReplicant2:创建Dicom文件的副本。 Volume1使用自我Dicom解析器,但Volume2使用Ruby Dicom

    Ruby DICOM 库可能支持 DICOM 标准的最新版本,并且通过社区的贡献持续更新和改进。此外,利用库的好处是它可以与其他 Ruby 应用程序更好地集成,使得开发更加高效,减少了出错的可能性。 在 DICOMReplicant2 的...

    oniguruma-6.9.5_rev1.tar.gz

    1. 改进的性能:Oniguruma 6.9.5_rev1在正则表达式匹配速度上进行了优化,提供更快的搜索和替换功能,使得在处理大量数据时更为高效。 2. 更多的正则表达式语法:除了基础的Perl和PCRE语法,此版本还增加了对更多...

    rrr:Ruby源代码搜索引擎-Search source code

    `rrr` 必须深入理解 Ruby 语言的特性,包括但不限于类、模块、方法定义、变量、常量、块、元编程等。这样才能正确解析和索引代码,使得搜索能够精确匹配到用户所需的代码片段。 ### 3. 搜索功能 用户可以通过...

    Java SE 6 新特性

    9. **改进的调试和诊断工具**:JConsole、VisualVM等Java Mission Control的组件在Java 6中得到增强,为开发者提供了更强大的性能分析和故障排查能力。 10. **Java Plug-in和Java Web Start更新**:Java插件和Web...

    Java1.6.zip

    7. **改进的JMX(Java Management Extensions)**:JMX在Java 1.6中得到了加强,提供了更好的远程管理能力,让开发者能更容易地监控和管理Java应用程序。 8. **安全增强**:Java 1.6加强了安全模型,引入了新的安全...

    MySQL_5.6.22_win32_XiaZaiBa

    对于开发人员,MySQL 5.6.22提供了更多的编程语言支持,包括Python、Ruby等,以及改进的JSON支持,预示着MySQL开始向NoSQL领域靠拢。同时,新的API和工具,如MySQL Shell,为数据库的管理和操作提供了更直观的界面。...

Global site tag (gtag.js) - Google Analytics