新聞中心
我們都知道在編譯Ruby的時(shí)候你需要使用configure的 --disable-pthread參數(shù)。沒錯(cuò),在configure --disable-pthread 可以讓你得到大約 30% 性能提高。但是,這是為什么呢?

創(chuàng)新互聯(lián)公司主要從事成都做網(wǎng)站、網(wǎng)站制作、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)衢州,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):028-86922220
所有的這一些我們需要使用 strace 工具,這個(gè)工具可以打出所有的真實(shí)的操作系統(tǒng)的調(diào)用。
下面,是一段我們測試的例程:
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引擎,那么我們可以得到下面這樣的結(jié)果:
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> |
你會(huì)發(fā)現(xiàn)上面的sigprocmask 系統(tǒng)調(diào)用一頁一頁又一頁地沒完沒了的。如果你用 strace -c,你會(huì)發(fā)現(xiàn)一共大約20,054,180 個(gè)sigprocmask系統(tǒng)調(diào)用。但是,如果你是在--disable-pthread 的Ruby版本下運(yùn)行,你會(huì)發(fā)現(xiàn)根本沒有那么多的sigprocmask 系統(tǒng)調(diào)用(只有 3 次,簡直就是天壤之別)
查看一下源代碼
我們知道 configure 是一個(gè)腳本,其主要用來創(chuàng)建一個(gè) config.h 文件,其中有一大堆宏定義 defines ,這些宏定義決定了使用什么樣的函數(shù)。所以,讓我們來比較一下版本 ./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 |
好的,現(xiàn)在我們再 grep 一下Ruby的源代碼,我們可以看到只要HAVE_[S/G]ETCONTEXT 被設(shè)置了,Ruby 就會(huì)調(diào)用setcontext() 和getcontext() 這兩個(gè)系統(tǒng)調(diào)用來存取context 的狀態(tài),以便異常處理時(shí)的切換(通過EXEC_TAG)。
而如果 HAVE_[S/G]ETCONTEXT 沒有被定義 的情況下,Ruby 會(huì)使用 _setjmp/_longjmp這兩個(gè)系統(tǒng)調(diào)用。
我們來看看 _setjmp/_longjmp 的man page:
… The _longjmp() and _setjmp() functions shall be equivalent to longjmp() and setjmp(), respectively, |
還有setcontext /getcontext的 man page:
… uc_sigmask is the set of signals blocked in this context (see sigprocmask(2)) … |
我們可以看到 getcontext 調(diào)用每次都要調(diào)用sigprocmask 但是_setjmp 不會(huì)。
補(bǔ)丁
通過補(bǔ)丁增加了一個(gè)configure 的參數(shù) --disable-ucontext 其可以讓你關(guān)閉使用 setcontext或getcontext,你只需要像如下方式使用就好了。
./configure --disable-ucontext --enable-pthread |
補(bǔ)丁下載:http://github.com/ice799/matzruby/commit/0b9b69f9653782a33aee2b8937d405eae245b60c
如果你以這種方式編譯Ruby,那么,你的程序的性能在同等條件下可能會(huì)有30%左右的提升。
【編輯推薦】
- Ruby語言的發(fā)展趨勢和啟示
- Ruby on Rails為企業(yè)SOA做好準(zhǔn)備了嗎
- 腳本語言排行榜 PHP、Ruby和Python領(lǐng)先
文章題目:讓Ruby性能增加30%的改進(jìn)方法分析
本文來源:http://www.dlmjj.cn/article/codhhid.html


咨詢
建站咨詢
