写点什么

性能快报:Heap Stacks 提升 1.8.x 线程性能 & MacRuby AOT & ZenProfile 和 EventHooks

2009 年 5 月 27 日

Ruby 1.9 把 Ruby 世界从 1.8.x 的用户空间线程(userspace thread)系统带入原生线程(native thread)。尽管全局 VM 锁(Global VM Lock,VM)仍然影响着 1.9 的原生线程,使得每次只有一个 Ruby 线程能被执行,但是向原生线程的转变也带来了其它的好处。

Joe Damato 对 Ruby 1.8.x 的线程实现中的一个问题进行了研究,在 1.9 中由于原生线程的引入,该问题不复存在。简单地说:由于线程的上下文切换会导致线程栈内容的完全复制,如(针对挂起线程)从栈到堆的方向,还有针对被调度线程的另一方向,这样做开销非常巨大。大凡栈分配得大或者带有巨大栈帧(stack frame)的应用程序,都难拒其扰。

通过维持多个栈并在这些栈之间进行切换,原生的线程实现就不用担心出现这种低效率情况的尴尬了。Joe 的文章详细描述了他的“heap stacks”方案,并把这套方案带到了 Ruby 1.8.x 上。

如此一来,结果非常明显地体现在了性能的提升上──2 至 10 倍的性能改善,这使得基准测试的结果一举逼近 1.9.1。

从 GitHub 上我们可以找到给 1.8.6 1.8.7 打过补丁的代码。

Heap Stacks 方案是为了根除 Ruby 1.8.x 中最大的低效率问题的又一次尝试,除此之外,另一个就是解决了部分长期困扰 Continuation 和 GC 方面问题的 MBARI 补丁

条条大路通罗马,要让 Ruby 实现更高的性能,别的路也行得通:就在不久前,MacRuby 项目开始了实现基于 LLVM 的 VM 的工作。现在这项工作已经有一部分被用来为 Ruby 创建一个提前编译(Ahead Of Time,AOT) 的编译器了。在这里,AOT 是和 JIT(Just In Time,实时)编译器相对应的──也就是说,AOT 编译器的运行,并非在运行期编译,而是从源码生成出可执行文件

表达式会被编译成 LLVM IR,然后转换成位码(bitcode),再变成汇编语句,最后变成机器码。这是真正的编译 :-)

对于许多场景这样做确实是很有用的

这样做有利于 1) 代码混淆,及 2) 在动态代码生成不允许的环境下使用 Ruby。

最后,剖析器(profiler)可以用作来发现应用程序瓶颈的一种手段。Ryan Davis更新了他的 zenprofile 剖析器。该剖析器使用 Ruby 运行时的事件钩子作为跟踪方法调用的有效方式。说起来 Zenprofile 也颇有一段历史了,不过目前更新的版本依赖于 event_hook ──这个 gem 把建立钩子所须的原生代码单独抽取了出来。藉由 event_hook,我们可以不必大费周章地通过编写原生代码给 Ruby 解释器挂上钩子,现在只需编写纯 Ruby 代码就可以实现事件钩子了。Zenprofile 使用了 event_hook,提供了一套剖析逻辑的纯 Ruby 版本,以及使用了 RubyInline 和 C 作为原生代码的一套更快的版本。

简单看一下 zenprofile 的代码,我们可以发现使用 event_hook 非常简单,只需要扩展EventHook类,然后覆盖某些方法,如def self.process event, obj, method, klass,就可以捕获事件了。

Zenprofile 还提供了可用于关注个别方法性能的spy_on功能。该功能可通过 Ruby 代码进行配置,如要关注Integer#downto的性能,下面是一段来自misc/factorial.rb的例子:

require 'spy_on'
Integer.spy_on :downto

查看英文原文: Performance Roundup: Heap Stacks Boost Threads in 1.8.x, MacRuby AOT, ZenProfile and EventHooks

2009 年 5 月 27 日 09:30531

评论

发布
暂无评论
发现更多内容

[翻译]分布式系统的模式-综述

流沙

架构 分布式系统

推荐Scrum书籍

Bob Jiang

Scrum 敏捷

两数之和

书旅

数据结构 算法 数据结构与算法

架构师0期Week10作业2

Nan Jiang

看DLI服务4核心如何提升云服务自动化运维

华为云开发者社区

Serverless 运维 运维自动化 华为云 DLI

数据仓库

JackWangGeek

环信助力OFashion迷橙开辟海外直播带货新通路

DT极客

一文熟悉MySQL索引

书旅

MySQL 索引

如何有效防止sql注入

Java旅途

troubleshoot之:使用JFR解决内存泄露

程序那些事

Java 内存泄露 性能调优

如何优雅的编写GO程序?

八两

go 优雅 语法

5G从小就梦想着自己要迎娶:高速率、低时延、大容量三个老婆

华为云开发者社区

5G IoT 通信 华为云 NB-IoT

区块链跨境承兑商支付系统开发,usdt支付平台搭建

WX13823153201

区块链 数字货币

Web前端性能优化,应该怎么做?

华为云开发者社区

运维 前端 HTTP js 前端性能优化

常见的BI项目问题和解决方案

JackWangGeek

架构师训练营第十周作业

邵帅

可读代码编写炸鸡十 - 保持单纯

多选参数

代码质量 代码 代码优化 可读代码编写 可读代码

有意思:Go函数的闭包

申屠鹏会

go 闭包 函数

Newbe.Claptrap 框架如何实现 Claptrap 的多样性?

newbe36524

容器 微服务 .net core ASP.NET Core

一文读懂GaussDB(for Mongo)的计算存储分离架构

华为云开发者社区

数据库 mongodb 数据 GaussDB 存储分离

吴桐:数字货币具有稳定的避险性吗

CECBC区块链专委会

区块链 数字货币 链政经济

第十周.命题作业

刘璐

关键绩效指标KPI

JackWangGeek

window form自定义控件类型

JackWangGeek

架构师训练营第十周总结

邵帅

数据挖掘

JackWangGeek

SSAS查询性能最佳实践

JackWangGeek

微软BI解决方案的优势

JackWangGeek

什么是死信队列

Java旅途

RabbitMQ

SSIS主要功能

JackWangGeek

架构师0期Week10作业1

Nan Jiang

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

2021年全国大学生计算机系统能力大赛操作系统设计赛 技术报告会

性能快报:Heap Stacks提升1.8.x线程性能 & MacRuby AOT & ZenProfile和EventHooks-InfoQ