CentOS 5.1 の perl をリビルドする
2008-12-26 追記
CentOS 5.2 の updates の perl-5.8.8-15.el5_2.1 で下記該当パッチ+αがあたった状態になっています。もう自分でパッチをあててリビルドする必要はありません(RHEL 5(.2) の perl-5.8.8-15.el5_2.1 で例のバグが治っていた - daily dayflower)。
overload の rebless バグとパフォーマンスペナルティ問題
については下記参照。
どのプロダクトが影響をうけるのか
2008/01/07 時点での RedHat の perl パッケージについて調べてみた結果。
ディストリビューション | RPM バージョン | overload バグ | パフォーマンス悪化 |
---|---|---|---|
素 5.8.8 | - | × | - |
素 >= 5.9.4 | - | ◎ | ◎ |
FC 6 | 5.8.8-12 | ○ | × |
Fedora 7 | 5.8.8-27.fc7 | ○ | ○ |
RHEL 5.1 | 5.8.8-10.el5_0.2 | ○ | × |
RHEL 5.2 (up) | 5.8.8-15.el5_2.1 | ○ | ○ |
表のヘッダと◎○×がわかりにくいですけど気にしないでください*1。×はよくないって意味です。
で,overload のバグが顕在化することはあんまりないので patch#27512 をはずしてリビルドするのが定説なんですが(Perl 5.8.8 の仕様といえばそれまでですし),Fedora 7 / 8 あたりではきちんと治っているのがムカツク!つか標準パッケージで遅いのがもっとムカツク!
ので,CentOS 5 でも overload バグに対処しつつパフォーマンス劣化を防いでみます。
CentOS 5.1 用にリビルドする
方針としては,
- Fedora 7 用の SRPM から patch#28775 を取り出し
- CentOS 5.1 用の spec に追加する
です。今回は x86_64 環境用の記述なので適宜読みかえてください。
まず Fedora 7 用の SRPM をとってきます(後々 patch#28775 を抽出するため)。また,CentOS 5.1 用の SRPM をインストールします。
% cd % wget http://ftp.iij.ad.jp/pub/linux/fedora/updates/7/SRPMS/perl-5.8.8-27.fc7.src.rpm % rpm -ivh http://ftp.iij.ad.jp/pub/linux/centos/5.1/updates/SRPMS/perl-5.8.8-10.el5_0.2.src.rpm
CentOS 5.1 用の 10.el5_0.2 の RPM spec ファイルに下記のパッチを当てます。
--- SPECS/perl.spec.dist 2007-10-24 01:16:56.000000000 +0900 +++ SPECS/perl.spec 2008-01-07 18:33:31.000000000 +0900 @@ -162,6 +162,7 @@ Patch27426: perl-5.8.8-U27426.patch Patch27509: perl-5.8.8-U27509.patch Patch27512: perl-5.8.8-U27512.patch +Patch28775: perl-5.8.8-U28775.patch Patch27604: perl-5.8.8-U27604.patch Patch27605: perl-5.8.8-U27605.patch Patch27914: perl-5.8.8-U27914.patch @@ -373,6 +374,8 @@ %patch27512 -p1 +%patch28775 -p1 + %patch27604 -p1 %patch27605 -p1 @@ -595,6 +598,9 @@ %changelog * Tue Oct 23 2007 Robin Norwood <rnorwood@redhat.com> - 4:5.8.8-10.el5.2 +- Resolves: rhbz#196836 +- Apply upstream patch #28775, which fixes an issue where reblessing + overloaded objects incurs significant performance penalty - Resolves: bug#323811 - fix previous patch
patch#27512 があたりっぱなしになっているのが気になりますが,Fedora 7/8 の spec でもあたりっぱなしなので踏襲しました。これはやっぱ必要みたい。
さて,上記ファイルをたとえば perl-spec.patch などの名前で保存し,patch をあてます。
% cd ~/rpmbuild % patch -p0 < ~/perl-spec.patch
次に,先ほど述べたように Fedora 7 用の SRPM から patch#28775 を抽出して SOURCES
フォルダに置きます。
% cd ~/rpmbuild/SOURCES % rpm2cpio ~/perl-5.8.8-27.fc7.src.rpm | cpio -i perl-5.8.8-U28775.patch 20436 blocks
% cd ~/rpmbuild % rpmbuild -bb SPECS/perl.spec
作成できたら(なるべく perl 系が常駐していない環境で)旧 perl のパッケージを削除し,ゴミを削除して新しいパッケージをインストールします。
% sudo rpm -e --nodeps perl % sudo rm -r /usr/lib/perl5/5.8.8 % sudo rm -r /usr/lib64/perl5/5.8.8 # 下記 2 件はお好みで % sudo rm -r /usr/lib/perl5/site_perl/5.8.8 % sudo rm -r /usr/lib64/perl5/site_perl/5.8.8 % sudo rpm -ivh ~/rpmbuild/RPMS/x86_64/perl-5.8.8-10.2.x86_64.rpm
うまくいったか
Yappo さんのベンチマークをとってみます。
% perl yappo.t Benchmark: timing 1000000 iterations of not overload, overload... not overload: 1 wallclock secs ( 1.68 usr + 0.00 sys = 1.68 CPU) @ 595238.10/s (n=1000000) overload: 2 wallclock secs ( 1.69 usr + 0.00 sys = 1.69 CPU) @ 591715.98/s (n=1000000)
無事パフォーマンスペナルティがなくなりました。とぅっとぅるー(^ω^)
overload のバグについても,
% cat > overload.pl #!/usr/bin/perl use strict; use warnings; package Stringify; use overload q{""} => sub { 'Hi!' }; package main; my $a = { }; my $b = $a; bless $a, 'Stringify'; print $b, "\n"; ^D % perl overload.pl Hi!
きちんと対応できてます。