なぜページ数が増えると AutoLink は動作しないのか

  • ページ: BugTrack2
  • 投稿者: bee
  • 優先順位: 低
  • 状態: 提案
  • カテゴリー: 本体バグ
  • 投稿日: 2016-11-26 (土) 08:50:05
  • バージョン:

メッセージ

ページ数が増えたとき、AutoLink が原因で正常に動作しなくなると言われている(関連: BugTrack2/81)。

しかし、AutoLink の何が原因なのかコメントを追っていってもよく分からなかった。

  • PCRE の問題?
    • サブパターン数の限界?
  • メモリ使用量の問題?
  • CPU 時間の問題?

原因はさておき、効率の良い正規表現を生成するライブラリとして Regexp-Assemble が知られている。
PukiWiki でも henoheno さんが generate_trie_regex() という関数を作成している(1.5 には未マージ)。

しかし、何が原因なのか分からなければベンチマークも取れないし、改善したか(もしくは悪化したか)確認するのも難しい。
そこで AutoLink が動作しない条件を調べたい。
もとい「詳しい人がいたら教えてほしい」という Bug です。


  • ニコニコ大百科のタイトルを食わせてみたところ
    "preg_match(): Compilation failed: regular expression is too large at offset 3339719"
    という WARNING を吐いてくれました。 -- bee 2016-11-26 (土) 10:54:37
  • www.pcre.org/pcre.txt によると 64K data units を越えてはいけないらしい。 -- bee 2016-11-26 (土) 11:09:41
  • blog-tmtsts.rhcloud.com/135 の方法を試したところ、32765 Byte で私の環境も WARNING が出ました。 -- bee 2016-11-26 (土) 11:11:33
    • pcre.backtrack_limit/pcre.recursion_limit の設定を一桁ずつ増やしてみたが当然ながら効果なし。 -- bee 2016-11-26 (土) 11:19:18
  • bit.ly/2fitPfD で
    pukiwikiベースのwikiだと日本語名のページは900ページ前後(略)でホワイトアウトして文字が見えなくなる表示上のバグがある
    と言われていたのが不思議だったのですが、日本語が 3 バイトでページ名が平均 12 文字程度とすると 900 ページで 32KB を使い切りますね。なるほど。 -- bee 2016-11-26 (土) 11:38:20
  • まあとりあえず preg_replace_callback の戻り値をチェックするようにしたほうがいいですね。ページが真っ白になるのは NULL を素通りさせているせいだと思われるので…。 -- bee 2016-11-26 (土) 11:43:38
  • 意欲的なIssueですね。個人的にAutoLinkは利用していないのですが、よく使われているのでしょうかね。確かにGoogle検索するとこの制限にかかっている人がちらほら見られます -- umorigu 2016-11-26 (土) 22:35:40
    • コラボレーションツール、辞典、日記などいろんな用途のうち、AutoLink を使いたいパターンは限られているような気はしますね。 -- bee 2016-11-27 (日) 08:28:16
  • preg (PCRE) の代わりに mb_ereg(鬼車)を使う選択肢もあります。鬼車は PCRE のような制限がないらしく普通に動作しました。次は「AutoLink のメモリ使用量が多すぎて何も表示されなくなる」という報告が来ることになりそうですが…。 -- bee 2016-11-27 (日) 08:54:01
  • こんにちは。最新のソースの中にあるgenerate_trie_regex() は元々どなたかが作られた美しい関数を再構成したもので、私が作成したものではありません。AutoLinkには「処理できるサイズを超え(う)る」という設計上の課題があるので、そこを打破できない限り問題は収まらないと思われます。 -- henoheno 2016-11-27 (日) 21:33:56
    • autolink.dat にただ一つの正規表現を収めることをやめて、何らかの条件で分割した複数個の正規表現を格納する方式に改める必要がある、ということです。 -- henoheno 2016-11-27 (日) 22:58:36
      • はい。この問題は 1) 正規表現を適切に分割する 2) 正規表現を効率化する 3) 特定の名前空間を除外できるようにするなどしてユーザーが正規表現を短くできる仕組みを作る…といった複数の解決策が必要です。 -- bee 2016-12-01 (木) 11:58:34
    • おっと、また勘違いをしました。すみません > generate_trie_regex() の件 -- bee 2016-12-01 (木) 11:46:34
  • mb_regを使うだけで改善されるんですか。それはいいですね。副作用を確認しておきたいです -- umorigu 2016-11-29 (火) 07:56:04
    • 目下最大の障害は mb_ereg_replace_callback() が PHP 5.4.1 以降の関数で、preg_replace_callback() の代替が PHP 4〜5.3 にないという点ですね…。 -- bee 2016-12-01 (木) 12:01:06
    • すべてのPHPバージョンで同じ機能・制約にする必要はなく、mb_ereg_replace_callbackの有無で処理を分ける方法もあります。例えばbugtrack_listキャッシュはPHP5.4以降のみで動くようにしました -- umorigu 2016-12-02 (金) 08:50:00
    • 了解です。packagist.org/packages/gobie/regex のベンチマークによれば preg_replace_callback/mb_ereg_replace_callback の性能差はほぼありません。あとは正規表現が長くなれば当然メモリ消費量も増えるため、PHP のメモリーリミットに引っかかりやすくなり、今よりひどい挙動になるのではないか、という懸念があります。 -- bee 2016-12-03 (土) 00:04:27
  • このBugTrackの趣旨とは少しずれますが、今のロジックで改善できるところまではして、それ以上はクライアント側の処理にするのが良いのかなと思ってます。つまりページリストをブラウザに渡して、JavaScriptでリンク作成するような仕組みです。もっとも、数万ページになるとリストだけでMB単位になってしまうので別の工夫も必要になります -- umorigu 2016-11-29 (火) 07:57:14
    • 別の理由からクライアント側の処理にする必要があると思います。本当は DOM を解析してテキストノードだけに AutoLink を適用するべきなのですが、現在の AutoLink はかなり Hacky に動いています。正規表現でマッチさせる部分はサーバー側で行いつつ、実際に適用するのはJavaScript で行うようにしたほうが確実です。 -- bee 2016-12-01 (木) 12:09:57
    • JavaScript に頼ると携帯で AutoLink が使えなくなるという問題も一応指摘しておきます。 -- bee 2016-12-01 (木) 12:12:42


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-12-03 (土) 00:04:27
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.323 sec.

OSDN