# HG changeset patch # User Ryoma SHINYA # Date 1294378616 -32400 # Node ID 107d09e097d8c927759a1fce487ff52ba4360e45 # Parent 59d695a30f5ed9877cdf5a1ea90873bb696cc5fb add appendix. diff -r 59d695a30f5e -r 107d09e097d8 presen/index.html --- a/presen/index.html Thu Jan 06 23:49:31 2011 +0900 +++ b/presen/index.html Fri Jan 07 14:36:56 2011 +0900 @@ -28,6 +28,7 @@ img#me04 {top: 44px;} img#me05 {top: 43px;left: 36px;} #tbcom td, #tbcom th, #tbcom {border: 1px solid black; padding: 2px;} + .tbl td, .tbl th, .tbl {border: 1px solid black; padding: 2px;} @@ -39,12 +40,12 @@
-

動的なコード生成を用いた
正規表現評価器の実装

+

動的なコード生成を用いた
正規表現マッチャの実装

新屋 良磨, 河野 真治

琉球大学 並列信頼研究室

@@ -53,42 +54,81 @@

研究目的と背景 (1)

    -
  • 正規表現は, パターンマッチによるテキストの検索等に利用されている.
  • -
  • シンプルで保守性に優れ, かつ性能の高い正規表現マッチャを実装したい.

  • -
  • プログラムの開発は, 生産性の高い言語によって行われることが開発者にとって望ましい.
  • -
  • 開発効率 or 実行効率 ?
  • +
  • 当研究室では, 継続を基本としたプログラミング言語 Continuation based C (CbC)を開発している.
  • +
  • この言語は, Cから関数呼び出しや for ループ制御などを」覗き, 同等の動作はすべて継続でを用いて実現することで, Cよりも細かい動作を可能にしている.

  • +
  • 本研究では, CbC の特徴を生かす例題として, 正規表現エンジンに着目した.

研究目的と背景 (2)

    -
  • 生産性の高い言語によって実装したプログラム(生成系)から, 抽象度が低く性能の高い言語のコード生成を行うプログラミング手法がある.
  • +
  • シンプルで保守性に優れ, かつ性能の高い正規表現エンジンの実装が望ましい.

  • +
  • 生産性の高い言語によって実装したプログラム(生成系)から, 抽象度が低く性能の高い言語(CbC/C/Assembly)のコード生成を行うプログラミング手法がある.
  • この手法では, 性能を保ったまま開発効率に優れるという利点がある.

  • -
  • そこで本研究では, 与えられた正規表現を認識するコード(C言語等の)を生成する正規表現評価器の実装を行った.
  • +
  • そこで本研究では, 与えられた正規表現を認識するCbCによって記述されたソースコードを生成する正規表現エンジンの実装を行った.
+

発表内容

+
    +
  1. CbC の紹介
  2. +
  3. コード生成による正規表現エンジンの実装法
  4. +
  5. 比較検証(grep)
  6. +
  7. まとめ
  8. +
+
+ +
+

Continuation based C (1)

+

状態遷移記述をベースとした、より細かい単位でのプログラミングを実現する.


+
    +
  • 環境を保持しない継続、軽量継続を導入. 軽量継続で状態遷移が明確になる.
  • +
  • C言語などの関数よりも小さなプログラミング単位として, コードセグメントを持つ.
  • +
  • 関数 > コードセグメント > ステートメント
  • +
+
+ +
+

Continuation based C (2)

+

継続

+
    +
  • 現在の処理を続行するための情報.
  • +
      +
    • Cならば続く命令のアドレスや,
    • +
    • 命令に必要な値,
    • +
    • スタックなど, その環境すべてを含む.
    • +
    +

+

CbCの軽量継続

+
    +
  • 継続からスタックに関する情報を落とす.
  • +
  • 続く命令とデータのみのシンプルな継続.
  • +
  • 軽量継続によって, より高度に最適化された状態遷移によるプログラミングが可能. -> 正規表現
  • +
+
+ +

正規表現とは

  • テキストのパターンマッチング記法.
  • ex: "(A|B)*C" -> "A"または"B", の0回以上の繰り返し直後に"C": "C","ABC","ABBBBC"

  • GNU grep などのテキスト検索ツール等で利用されている.


  • -
  • 正規表現は(NFAを経て)等価なDFA(決定性有限オートマトン)に変換可能.
  • -
  • 主張: DFAは直接コードで表現できる.
  • +
  • 正規表現は等価なDFA(決定性有限オートマトン)に変換可能.
  • +
  • 主張: DFAによる状態遷移は, CbCによる記述が適している.
-

本実装の特徴

+

正規表現マッチャの実装

  • DFAの状態遷移に対応した, 関数遷移を行うコードを生成.
  • -
  • 生成系はPythonで実装.
  • -
  • 正規表現の連接, 集合和, 閉包 の基本演算に対応.
    - "(A|B)*C" -> [[[AとBの集合和]の閉包]とCの連接]
  • +
  • 生成系はPython, CbCで実装.
  • +
  • 正規表現の連接, 集合和, 閉包 の基本演算及びいくつかの拡張記法に対応. + 例: "(A|B)*CD+[0-9]?"
  • マルチバイト文字: UTF-8 に対応(内部コード).
@@ -103,6 +143,7 @@
+

DFAからのコード生成

@@ -153,20 +195,7 @@
-

コード生成: CbC (1)

-
    -
  • CbC(Continuation based C)は
  • -
      -
    • 関数よりも小さなプログラミング単位としてコードセグメントを持つ.
    • -
    • コードセグメントによる継続を基本としたCの下位言語である.
    • -
    • CbCコンパイラがGCCを拡張する形で実装されている.
    • -
    -
  • DFAの遷移は継続的な処理であり, CbCではそれを明示的に記述できる.
  • -
-
- -
-

コード生成: CbC (2)

+

コード生成: CbC

  • CbCでも, 前節で紹介したCと同様に生成を行ったが, 関数ではなくコードセグメントを用いている.
  • @@ -213,7 +242,7 @@
             
    • コンパイル速度
      表: N個の単語の集合和から生成されたコードのコンパイル時間 (最適化有り(O3)).
    • - +
      @@ -247,8 +276,8 @@ 3つのパターンによるベンチマーク.
      N (単語数)110100
      C (GCC)0.34s0.78s4.27s
      CbC (GCC)0.75s1.03s9.43s
      - +
      fixed-string: 固定文字列
      simple-regex: 単純な正規表現
      complex-regex: 複雑な正規表現
      http-url-regex: RFC定義のURL正規表現

      "複雑さ" = 変換されたDFAの状態数/遷移規則の多さ.

      @@ -282,12 +311,12 @@
    • fixed-string - 固定文字列でのマッチング
      パターン : "Wikipedia" -
      - マッチ行数: 348936行

      + マッチ行数: 348936行





      マッチ時間:
    • - +
      - + @@ -296,36 +325,36 @@
      -

      ベンチマーク: simple-regex

      -
        -
      • - simple-regex - 単純な正規表現でのマッチング
        - パターン : "(Python|Perl|Pascall|Prolog|PHP|Ruby|Haskell|Lisp|Scheme)" -
        - マッチ行数: 15030行

        - マッチ時間 -
      • -
      本実装GNU grepcgrepGoogle RE2本実装GNU grep cgrep Google RE2
      1.57(+0.12) s2.59 s1.89 s30.10 s
      - - - - - - -
      本実装GNU grepcgrepGoogle RE2
      4.51(+0.41) s15.48 s6.42 s16.83 s
      -
    -
-

ベンチマーク: complex-regex

  • complex-regex - 複雑な正規表現でのマッチング
    - パターン : "http://((([a-zA-Z0-9]|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)*([a-zA-Z]|[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9])\.?|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(:[0-9]*)?(/([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*(;([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*(/([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*(;([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)*(\?([-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?)?" -
    + パターン : "(Python|Perl|Pascall|Prolog|PHP|Ruby|Haskell|Lisp|Scheme)" -
    + マッチ行数: 15030行





    + マッチ時間 +
  • + + + + + + + +
    本実装GNU grep cgrep Google RE2
    4.51(+0.41) s15.48 s6.42 s16.83 s
    +
+
+
+

ベンチマーク: http-url-regex

+
    +
  • + http-url-regex - RFC定義のURL正規表現
    + パターン : "http://((([a-zA-Z0-9]|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)*([a-zA-Z]|[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9])\.?|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)(:[0-9]*)?(/([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*(;([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*(/([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*(;([-_.!~*'()a-zA-Z0-9:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)*)*(\?([-_.!~*'()a-zA-Z0-9;/?:@&=+$,]|%[0-9A-Fa-f][0-9A-Fa-f])*)?)?"
    マッチ行数: 110411行

    マッチ時間:
  • - + @@ -340,27 +369,15 @@
  • 生成系を開発効率に優れた言語であるPythonで実装することで, 少ない記述量で正規表現評価器を実装した.
  • 本実装GNU grepcgrepGoogle RE2本実装GNU grep cgrep Google RE2
    2.20(+0.40) s51.43 s2.62 s85.12 s
    +
    本実装 (Python): 1500行 (C生成系: テストコード含む)
    本実装 (CbC): 1400行 (C生成系,最小実装)
    GNU grep (C): 15000行 (コアのみ)
    -
  • 最終的に得られた正規表現評価器の性能は, GNU grep に勝るテストケースもあり, 性能も良い.
  • +
  • 最終的に得られた正規表現評価器の性能は, どのテストケースにおいても 他のgrep より 2~20倍, ほど高速な結果がでており, 性能は非常に高い.
  • 目的: シンプルで保守性に優れ, かつ性能の高い正規表現マッチャを実装したい.
-

今後の課題

-
    -
  • 正規表現評価器の機能強化
  • -
      -
    • 固定文字列フィルタリング(Boyer-Moore等)や後方参照の実装等.
    • -
    • 後方参照: "(A*)B\1" -> "\1"は(A*)でマッチした文字列.
    • -
    • 本実装は関数遷移によるマッチングを行うので, バックトラック処理を容易に記述できる.
    • -
    -
  • コード生成の最適化, 生成手法の評価.
  • -
-
- -

展望

  • grep 以外のソフトウェアへの応用
  • @@ -375,7 +392,16 @@
-

付録: UTF-8

+

appendix: 色々な高速化

+
    +
  • 生成系自身の高速化 (CbCで書きなおし)
  • +
  • スレディッドコード (thanks Mr. Sasada)
  • +
  • 固定文字列フィルタリング(BMH, Quick-Search, 簡易フィルタ).
  • +
+
+ +
+

appendix: UTF-8

  • Unicodeの符号化形式 -> マルチバイト文字に対応.
  • 符号単位は8bit.
  • @@ -394,6 +420,7 @@
  • 入力の最小単位として, Unicode文字単位でNFA,DFAを構築すれば良い.
  • GNU grep 2.5.X では, DFAの遷移毎に入力文字に対して mbrtowc() を用いてwchar型への変換を行っている -> ボトルネック (90%以上)
  • +
  • GNU grep 2.5.X の場合, テストケースcoplex-regex において 190[s] 程かかる(!!) -> 2.6/ 2.7 を使いましょう.