タグ

ブックマーク / gfx.hatenadiary.org (9)

  • XSでメモリークを避けるたった一つの方法 - Islands in the byte stream (legacy)

    XSでメモリリークを避ける基原則は、それほど難しくない。すなわち、作ったSV(およびSVファミリ)はすぐsv_2mortal()するのである。mortalなSVはスコープ*1から抜けるときに解放されるため、メモリリークは起こらない。つまり、あるスコープ内で新しく作ったすべてのSVをmortalな状態にしておくということだ。 この原則のもとでコードを書くと、誤ってリファレンスカウントを増やさなかったケースでは警告が頻繁に起きる。しかし、少なくともメモリリークは起こらない*2。メモリリークの検出は難しいので、警告が出るのは福音であろう。 もちろんこれは原則で、メモリリークにまつわることで覚えなければならないことは決して少なくない。 たとえば、XSUBの戻り値をSV*にするとき、sv_2mortal(RETVAL)してはいけない。これはPerlの仕様ではなくxsubppが勝手にsv_2mort

    XSでメモリークを避けるたった一つの方法 - Islands in the byte stream (legacy)
  • B::Foreach::Iteratorでforeachイテレータを進める - Islands in the byte stream (legacy)

    B::Foreach::Iteratorというモジュールを書いた*1。 use B::Foreach::Iterator 0.02; foreach my $key(foo => 10, bar => 20, baz => 30){ printf "%s => %s\n", $key => iter->next; } iter->next()*2はforeachループのイテレータをひとつ進め、その値を返す。 また、iter->peek()はイテレータを進めることなく、次のイテレータを返す。 このモジュールを実装するにあたってpp_hot.cのpp_iter()を読んだのだが、確かにforeach ($min .. $max)は内部で配列を生成していない。また、foreach (reverse ...)についても最適化が行われており、reverse()した一時配列を作るのではなく、イテレータ

    B::Foreach::Iteratorでforeachイテレータを進める - Islands in the byte stream (legacy)
  • [Perl]UTF8-flagged strings affects regexps with the "i" modifier - Islands in the byte stream (legacy)

    HTML::FillInForm::Liteの使いどころという記事で,HTML::FillInForm::Liteが遅いということが取り上げられていた。 試しに記事内のベンチマークを行ったところ,確かに遅い。 # HTML::FillInForm 1.06 Benchmark: HTML::FillInForm vs. HTML::FillInForm::Lite Rate fillinall_lite fillinall fillinpart_lite fillinpart fillinall_lite 570/s -- -52% -76% -78% fillinall 1199/s 110% -- -49% -54% fillinpart_lite 2349/s 312% 96% -- -9% fillinpart 2595/s 355% 116% 10% --ところで,このベンチマー

    [Perl]UTF8-flagged strings affects regexps with the "i" modifier - Islands in the byte stream (legacy)
  • XS基礎文法最速マスター - Islands in the byte stream (legacy)

    元ネタ:Perl基礎文法最速マスター(id:perlcodesample) XSを始めるための手順といくつかの要素の解説です。C言語をある程度知っている人でも,これを読んだだけでXSの基礎をマスターしてXSを書くことができるようにはなっていません。リファレンスでもありません。 XSとは,狭義ではPerlでエクステンションを書くためのマクロ言語の名前ですが,広義ではエクステンションを書くための技術の総称です。ここでは,広義のXSを俯瞰します。 XSはいろいろと特殊なのでテンプレは無視で行きます。 目次: h2xsで空のディストリビューションを作る XSファイルの構成 スレッドコンテキスト SVファミリ GCとスコープ さらなる学習のために h2xsで空のディストリビューションを作る 以下のコマンドで空のXSディストリビューションを作ることができます。 h2xs -A -b 5.8.1 -n

    XS基礎文法最速マスター - Islands in the byte stream (legacy)
  • Perl/XSが得意なこと - Islands in the byte stream (legacy)

    最近ひたすらXSを書いていて思ったのが,XSはやっぱり速いということ。 ただ,いつでも無条件に速いというわけでもなく,何も考えずに書くとPurePerlのコードより遅くなることも珍しくない。実際,最近書いたShikaやMOPのXS版もいきなり高速だったわけではなく,一番最初のコードはPurePerlのほうが10%-30%ほど高速だった。 いろいろベンチマークをとった結果の感触として,XSの得手・不得手が分かってきたのでメモしておく。ちなみに下記で「注意を払う」というのは内部で呼ばれるmalloc()を極力減らすという意味で使っている。SVの生成自体はmalloc()を伴わないことが多い*1が,文字列の生成/連結や配列の生成/push/unshiftでは内部でmalloc()が呼ばれる可能性が高く,速度を落とす原因となる。 得手分野 ループ - XSのループが早いというより,Perlのループ

    Perl/XSが得意なこと - Islands in the byte stream (legacy)
    masakyst
    masakyst 2009/04/11
  • 「Perl/XSが得意なこと」の補足 - Islands in the byte stream (legacy)

    Perl/XSが得意なことはほとんどオレオレ用語といっていいくらい端折ったリストなので追々補足しておく。 まずひとつ,「注意を払う」というのは内部で呼ばれるmalloc()を極力減らすという意味と書いたが,よく考えてみればこれはmalloc()*1が遅いというのが問題なのではない*2。malloc()はそれだけで終わるものではなく,mallo()を呼ぶAPIの内部または前後ではデータのコピーが伴うのが普通だし,その前にSVの割りあてが必要だったり,あるいは一時SVを使うとなればENTER+SAVETMPS ... FREETMPS+LEAVEといったブロックスコープ管理ルーチンが伴ったりと,付随する様々な処理が加わることが極めて多い。だから避けるべきなのはmalloc()そのものというより,malloc()に付随する膨大な処理である。 具体的には,たとえばMOP.xsでは,メソッドやハッシ

    「Perl/XSが得意なこと」の補足 - Islands in the byte stream (legacy)
    masakyst
    masakyst 2009/04/11
  • XSでクロージャ - Islands in the byte stream (legacy)

    Perlのようにクロージャをサポートする言語では,eval()せずに実行時にサブルーチンを定義できるので大変便利である。しかし,Cではポータブルにクロージャを作る方法はないので,サブルーチンの動的定義とXSによる高速な実装は相容れないように見える。しかし,実際にはXSでもクロージャを作ることができる。というのも,Cの関数自体はデータを持てないが,newXS()で定義したCV(Code Value)はデータを持つことができるからだ。 そのためのスロットがSV全般に存在するMAGICスロットで,これは来はTie変数や%ENVなどの実装に使われるSVへの操作をフックするメカニズムである。しかしこの場合は,特定のCVとデータ(MAGIC構造体)を関連付けするためだけに使う。この関連付けられたデータCVの消滅と共に破棄されるので,クロージャの実装に使うことができる*1。 CVへの関連付けにはsv_

    XSでクロージャ - Islands in the byte stream (legacy)
    masakyst
    masakyst 2009/04/11
  • XSを書く難しさ - Islands in the byte stream (legacy)

    最近思うが,つくづくXSは難しい。いとも簡単にSEGVを起こし,デバッグが難しく,それゆえモジュール作者のやる気が失われたときのリスクが非常に大きい。そうやって多大なリスクを犯してXSを書いても,肝心の速度がPurePerl以上に遅いことも少なくない。 最近だとClass::MOPにパッチを送ったのだけど,その後幾度かのバグフィクスや修正を経た0.72現在,パフォーマンスがかなり落ちている。 最初のパッチでのパフォーマンス(いずれもPerl 5.8.9 linux multi-thread with -DDEBUGGING): Initialization: Rate pp xs pp 2327/s -- -18% xs 2844/s 22% -- Looking into the stash: Rate pp xs pp 20958/s -- -72% xs 73770/s 252% -

    XSを書く難しさ - Islands in the byte stream (legacy)
  • モダンなXSの書き方 - Islands in the byte stream (legacy)

    PerlのソースコードはPerl言語以上に変化が大きく,それに伴ってXSの書き方もだいぶ変わってきている。新しいAPIを使ったほうが可読性がよかったり高速だったり使いやすかったりする。 たとえば,スカラー(SV)から文字列(PV: pointer valueつまりchar*)を得るAPIの変遷は次のようになっている。 /* SV*からPVを得る古い書き方 */ STRLEN len; const char* pv = SvPV(pv, len); # pvとlen両方ほしいとき const char* pv_only = SvPV(pv, PL_na); # pvだけほしいとき /* その後SvPV_nolen()が追加され,PL_naはdeprecatedに */ const char* pv_only = SvPV_nolen(pv); /* 今は*_constが追加されたのでcons

    モダンなXSの書き方 - Islands in the byte stream (legacy)
  • 1