ptexenc/文字コード判定

ptexenc ライブラリ(ダウンロード [extlink])の PTEX_IN_FILTER + nkf コマンドを用いた、ソースの文字コードの自動判定機能は、なかなか普及しないので、対策を考えてみました。 文字コード自動判定は、pTeX の UTF-8 対応に並ぶ、重要な機能だと認識しているので、なかなか普及しないことは残念に思っています。

問題点

  1. 自分の環境は SJIS で統一されているから必要性を感じない by 大多数
  2. 速度低下が激しいので常用したくない by TeXnician
  3. nkf コマンドは用途が一般的すぎて TeX に必要なものとは思えないので TeX Live 2010 には含めない by TeX Live 開発者

1. は度外視します(爆)。 2. は PTEX_IN_FILTER だけの問題というよりは TeX の実装にも問題があります。 詳しくは後ほど説明しますが、意外なところに原因がありますし、根が深いです。 3. ですが、日本人にしか必要のない nkf コマンドを TeX Live に含めたくないという気持ちはよくわかります。そこに、日本人にとってどれだけ重要かを力説して取り込んでもらうのか、それとも穏便な別の方法を考えるのかは、よく作戦を練るべきところでしょう。

ptexenc-1.1.0 までの実装

C言語の fopen() でファイルを読み込むところを、フィルタプログラムを経由して読み込むように改造しました。 つまり、fopen() を popen() に置き換え、環境変数 PTEX_IN_FILTER に登録されたプログラムを起動して、その出力を読み取ります。

単純な改造の割には効果が大きく、いいアイデアだと思っていましたし、XeTeX にも似たような機能があるので、国際的にも正しい進歩をしていると思っています。 なお、ここに至るまでの経緯は ptetexWiki:UTF-8対応(3)(5)(6) も参考になります。

速度低下について

さて 2. の速度低下についてです。 nkf プロセスの生成や文字コード判定に時間がかかっていると想像するのが人の常でしょうが、それは半分は間違いです。

確かにプロセス生成 (fork) のコストは無視できません。しかし、それに輪をかけて問題なのが、今の TeX + WEB(2C) では、ファイルの存在チェックだけに fopen()/fclose() してくれることです。 つまり、fopen() しても、1文字も読み取らずに fclose() することが多々あります。 ですから、fopen() を単純に popen() に置き換えると、ファイルの存在チェックのたびに nkf のプロセスを生成してしまって、大きく速度低下していまいます。 これが PTEX_IN_FILTER の実装の問題点です。

解決策

そこで、次のような方法を実装しました。 この実装は、しばらく ptexlive(ダウンロード [extlink])の新しいものに紛れ込ませて公開してみます。落ち着いたら ptexenc の新バージョンに独立させます。

  • nkf をフィルタとして呼び出すのではなく、ptexenc ライブラリに内蔵しました。
  • ファイルを open しても、まだ文字コード判定を行いません。そのまま close されれば一切余分な計算時間はかかりません。
  • 文字を読み込む段階になって、その直前に初めて文字コード判定を行います。

PTEX_IN_FILTER と較べたメリットは次のようになります。

  • PTEX_IN_FILTER のような速度低下がありません。
  • 外部コマンドを呼び出さないので、セキュリティが向上します。
  • TeX Live には、nkf コマンドが TeX に依存しない一般的なツールだという理由で、取り込んでもらえてませんが、ptexenc の一部となることで、外国の人には気付かれないように(迷惑もかけないように)取り込んでもらえます。
  • UTF-8 <=> JIS のテーブルが iconv を使わずとも nkf 由来のものが手に入ります。TeX Live では好都合です。

逆に、デメリットもあります。

  • PTEX_IN_FILTER のようなフィルタ処理との相性は悪く、共存のためには複雑な処理を実現せねばなりません。
  • 文字コード判定の性能が nkf に固定されてしまいます。nkf 自体の普及度は高く、信頼性もあるとは思いますが、だからと言って pTeX に唯一の判定ルーチンとしてふさわしいと主張する根拠は見つかりません。もっとも、ふさわしくない理由も思いつきませんし、PTEX_IN_FILTER での使用実績もあるので、最有力であることは間違いありません。

簡単なベンチマークの結果です。Vine Linux 5.2, Core Solo U1300(1.06GHz)での実行時間(秒)です。速度低下がかなり防げていることがわかります。

手動nkf内蔵(今回)PTEX_IN_FILTER
jsclasses.dtx1.181.251.50
\input{5行}x1000回0.760.7912.0
\input{50行}x1000回1.591.8413.4

ご相談

  1. pTeX が(実質的に)nkf に依存してしまってよいでしょうか。ptexenc に nkf を取り込むので、アスキーさんに許可をいただく必要まではないと考えています。
  2. PTEX_IN_FILTER は廃止してもよいでしょうか。元々 Unix 版にしかなかったので、それほど影響は大きくはないと思います。もっとも、フィルタ機能は XeTeX にも別実装があるくらいに有力なものですが、その道を閉ざすことにもなるので、慎重に考えるべきだと思っています。
  • ありがとうございます。少し modify したものでテストさせていただきました。 \input{5行}x1000回で、性能が悪い計算機なのですが、約 1.15 倍しか時間がかからなくて、劇的に改善されています。元々 W32TeX では input に対するフィルタ機能は disabled にしていました。最近コード判別だけ nkf でするようにしていましたが、やはり ファイル全体に対するフィルタ機能は disabled のままでした。 性能はやはり場合によって10倍以上の時間を要していました。そのような事情で、W32TeXでは新しい ptexenc を使用させていただきたいと思います。よろしくお願いいたします。 -- kakuto 2011-03-21 (月) 12:45:00
  • 早速のテストありがとうございます。パッチの実装はあまり良くないので、すぐに差し替えます。ベンチマークに用いたサンプルを添付しておきます。 -- 土村 2011-03-21 (月) 13:49:31


添付ファイル: filepopentest.zip 14件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-03-21 (月) 13:49:31 (2438d)