2008年05月08日

font-familyに「メイリオ」を指定すると、Windows XP + IE6での表示がものすごく汚くなる件

 マイクロソフトから「メイリオ」(Meiryo)のWindows XP版がリリースされました。

XP用「メイリオ」フォントも公開 - ITmedia News
Microsoft、Windows XP向けメイリオフォントを公開 - PC Watch
Japanese ClearType fonts for Windows XP(ダウンロードページ)

 メイリオはWindows Vista用に開発されたClearType対応日本語フォントで、新しいスムージング技術に対応することで、非常に明瞭(Meiryo)な表示が可能だとされています。

 そこで、さっそくダウンロードし、Windows XPにインストール。自分のサイトのfont-familyにメイリオの指定も追加してみました。

font-family : 'メイリオ', 'Verdana', 'Helvetica', 'Arial', 'MS Pゴシック', 'MS P Gothic', 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'Osaka', 'Helvetica', 'Arial', 'Gothic', 'sans-serif';

 そしてリロード。

IE6でメイリオ


????!


メイリオ/MS Pゴシック比較表

 きれいに表示されるはずのメイリオで、文字が潰れてしまっています。特にFirefoxでは、font-weightの指定も効いていないのか、かなり貧相な表示になってしまいました。

 調べてみると、メイリオがきれいに表示されるのはIE7を使ったときだけで、それ以外では従来方式のアンチエイリアスもかからないということらしいです。

 そのため、font-familyにメイリオを指定すると、IE7以外ではかなり汚く表示されることになります。Firefoxの利用者が増える一方で、IE7がそれほど普及しているとも思えない現時点では、MS Pゴシックあたりを指定しておいたほうが無難のようです。無理をしてまでメイリオを使いたい理由もないですしねー

追記:
 「画面のプロパティ」の[デザイン]→[効果]→[次の方法でスクリーンフォントのふちを滑らかにする]で「ClearType」を有効にすれば、Windows XP上のIE6やFirefoxでもメイリオがきれいに表示されるようです。
 しかし、Windows XPではClearTypeがデフォルトで無効。ユーザーによる設定が必要になるので、やはり、font-familyへのメイリオ指定は避けておいたほうが無難そうです。

追記2:
 よく考えたら、わざわざメイリオをインストールしておいて、ClearTypeを無効のままにしておくってのは考えにくい。メイリオがあるときはメイリオを、なければMS Pゴシックを使うという設定で問題ないはず(下記はMac対策もしたfont-familyの設定の例)。

font-family : 'メイリオ', 'Meiryo', 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'MS Pゴシック', 'MS P Gothic', 'Osaka', 'Helvetica', 'Arial', 'Gothic', 'sans-serif';
posted by momose at 15:27| Comment(2) | TrackBack(0) | 技術TIPS/まとめ

2006年10月28日

[PHP] mb_ereg()じゃない、preg_match_all()に/uをつけるんだ!

ウノウラボ Unoh Labs: PHPのちょっとしたコツ

 最近のスクリプト言語は機能が多く、基本的な機能はほとんど実装されているので、アルゴリズムをどうこうするより、どの機能を使うか選ぶ方が重要だったりしますね(コーディングの効率的にも)。

 自分にもそういったレベルで気をつけていることがいくつかあります。

-[早起き生活]PHPのパフォーマンスチューニング
-[早起き生活]PHPのパフォーマンスチューニング その2:count()も使い過ぎると重くなる
-[早起き生活]PHPのパフォーマンスチューニング その3:APC投入

 あと、最近気づいたTIPSとしては、

日本語を正規表現検索したいときでもereg系の関数を使うのはやめとけ

なんてのもあります。

 PHPの組み込み正規表現関数にはPHP独自のereg系とPerl互換のpreg系がありますが、ヘルプに書いてあるとおり、ereg系の関数は出来があんまり良くありません。

注意: Perl 互換の正規表現構文を使用する preg_match() のほうが、多くの場合 ereg() よりも速く動作します。
PHPマニュアル:eregより

 なので、できる限りpreg系の関数を使いたいわけですが、検索対象や検索パターンに日本語が含まれているときは、日本語処理に対応したereg系の関数であるmb_ereg系の関数が使われることが多いようです。

 しかし、このmb_ereg系の関数もあんまり出来がよろしくなくて、たとえば、次のURLで紹介されているサンプルコードでは、「上」や「一」といった漢字がスルーされてしまいます。

「すべての漢字を取り出す正規表現」をPHPで試す

 どうも、mb_ereg系の関数では、UTF-8をうまく扱えないようです。

 では、PHPでUTF-8の正規表現を扱うには、正規表現検索処理を自作するか、EUC-JPといった別の文字コードに変換してからmb_ereg系の関数で処理するしかないのでしょうか?

 実は、preg系の正規表現にパターン修飾子「u」を指定すると、パターン文字列がUTF-8でエンコードされた文字列として扱われるようになります(古いPHPマニュアルにPCRE_UTF8でパターン文字列がShift-JISエンコードされた文字列として処理されるとか書いてあるのはおそらく間違い)。

PHPマニュアル:パターン修飾子

 先ほどの「上」や「一」をスルーしてしまうサンプルを、preg系の関数で書き直すと次のようになるでしょうか。

preg_match_all('/[一-龠]+|[ぁ-ん]+|[ァ-ヴー]+|[a-zA-Z0-9]+|[a-zA-Z0-9]+/u', $strToSplit, $aMatches);

 PHPの日本語正規表現処理まわりには、まだまだいろいろなトリビアがありそうな気がします。ほかにもあれば、教えてください。
posted by momose at 01:08| Comment(2) | TrackBack(1) | 技術TIPS/まとめ

2006年01月22日

[早起き生活]PHPのパフォーマンスチューニング その3:APC投入

 PHPのパフォーマンスチューニング最後の手段として、APC(Altenattive PHP Cache)を導入してみました。

http://pecl.php.net/package/APC

 APCは、いわゆるコンパイルキャッシュの一種です。

 コンパイルキャッシュを利用すると、通常はPHPスクリプトを実行するたびに生成される中間コード(VBやJavaのバイトコードみたいなもの)がファイルとしてキャッシングされるようになります。毎回のコンパイル処理が不要になるため、スクリプト実行の前処理が軽くなるというわけです。特に、早起き生活のように、コードにコメントが多かったり、ファイルがクラスごとに分けられているような場合には、かなりの効果が期待できそうです。

 PHP用のコンパイルキャッシュとしてはeAcceleratorなども有名ですが、PHPのバージョンが上がるたびに再インストールしなければいけないようなので、今回ははpearライブラリにも収録されているAPCを導入することにしました。

 APC自体は、コマンドラインから「pear install apc」とするだけでインストールできます(Cコンパイラやmake、phpize、aspxなどがインストールされていないと警告が出る場合は適宜apt-getでインストール)。

 その後、php.iniに次のような設定を書き込み、Apacheを再起動すれば、すぐに中間コードがキャッシングされ始めます。


extension=apc.so
[apc]
apc.optimization=1
apc.mode = mmap
apc.cachedir = /tmp
apc.check_compiled_source = 1
apc.check_mtime = 1


 手元の環境で確認したところ、ACP導入前は60ms程度かかっていたライブラリファイル読み込みまわりの処理が、導入後は10ms程度に高速化されていました(時々導入前より遅くなることもありますが)。

 さらに、MRTGのCPU使用率もピークが70%台から50%台に落ち着いています。

 ただ、ここのところさらにPVが伸びていて、転送量も11月にob_gzhandler(対応しているWebブラウザにたいしては出力を圧縮して転送するというPHPモジュール)を入れる直前のピークを突破してたりします。

 結果、ここ一連のチューニングで2〜3倍近く高速化されているはずなのに、サーバへの負荷はほとんど変わってなかったり。

 次はグラフ画像を小さくする方法を考えてみようかしらん。


 ところで、PHPコードの形で出力をキャッシュするタイプのテンプレートエンジンは、コンパイルキャッシュと組み合わせるとものすごく速くなったりするんでしょうか。だれか試してないかなぁ。
posted by momose at 20:15| Comment(0) | TrackBack(1) | 技術TIPS/まとめ

2006年01月21日

[早起き生活]PHPのパフォーマンスチューニング その2:count()も使い過ぎると重くなる

 PHPで配列を扱う場合、配列の要素数を調べるためのcount()関数をよく使います。
 たとえば、データベースから取得した行数を確認するために次のようにしたり、


if (count($aRows) > 0) { // データあり
 // データの処理
}


配列に読み込んだテキストを動的にスキャンするために次のようにするといった具合です。


for ($i=0;$i<count($aLines);$i++) {
 // 行に対する処理
}


 ただ、このcount()関数、実行1回あたりはたいしたことはないのですが、むやみに使いすぎるとやはりそれなりに重くなるようです。特に、forループの条件式に記述した場合は繰り返しのたびに呼び出されることになるため、かなりのオーバーヘッドが予想されます。

 ためしに、count()関数を1回だけ実行する次のようなコードと比較してみたところ、forループの条件式にcount()関数を記述すると、配列の長さによっては、2倍近く時間がかかるようでした。


$iLineCount = count($aLines);
for ($i=0; $i<$iLineCount; $i++) {
 // 行に対する処理
}


 一方、配列が空かどうかを確認するときも、count()関数の代わりにempty()関数を使うと、若干のパフォーマンスアップが期待できるようです。


if (!empty($aRows)) { // データあり
 // データの処理
}


 こちらは配列の長さとはあまり関係なく、実行1回あたり30%程度のパフォーマンスアップを確認できました。forループに比べると実行回数はたいしたことありませんが、サーバー全体で考えれば、少しは意味があるかもしれません。

 あと、ループがらみのオーバーヘッドといえば、ファイルの読み込み時によく使うwhile(!feof())ループも、次のようにするとパフォーマンスを改善できるそうです(こちらはヘルプに記載あり)。


do {
 $data = fread($fp, 8192);
 if (strlen($data) == 0) {
  break;
 }
 $file .= $data;
} while(true);


 fread()関数1回で読み込めるサイズのファイルを扱うような場合にはほとんど違いが出てきませんが、こういった処理は1度関数化しておけば使いまわすことができます。常にその関数を使うようにすれば、累積的な効果は期待できるのかもしれません。

(その3につづく)
posted by momose at 13:08| Comment(0) | TrackBack(0) | 技術TIPS/まとめ

2006年01月12日

[早起き生活]PHPのパフォーマンスチューニング

 年明けからじわじわとPVが上がり、それにつれてサーバーのロードアベレージも上がってきました。

 最初はDBまわり、もしくはファイル処理まわりがボトルネックになっているのかと思ったのですが、調べてみると自作のテンプレートエンジンが足を引っ張っていることが判明しました。いや、いちおうSmartyとかよりは軽いんですけどね。

 とはいえ、さらに重くなってサーバーを増強しなくちゃいけない事態になるのも面倒なので、先手を打ってテンプレートエンジンのパフォーマンスチューニングを行なっておくことにしました。

 PHPの文字列処理のパフォーマンスは、だいたい次のようなポイントを押さえれば、それなりに改善することができます。

・ereg系の関数は使わない。代わりにpreg系の関数を使う
・可能ならstr_replace()、strstr()といったより単純な関数を使う
・さらに可能ならstrpos()で代用する

 今回はこれで30%くらい、スクリプト全体では20%くらいのパフォーマンスアップを実現できました。

 テンプレート処理のパフォーマンスチューニング方法には、ほかにもキャッシングとかいろいろな手法があります。サーバーの負荷を見ながら順次こういった手法を取り入れていけばまだしばらくは大丈夫そうですが、どこかで急激にアクセスが増えたりすると追いつかなくなるかも?という気もしないでもありません。

 まぁ、その前に回線がダメになるでしょうけど。
posted by momose at 02:18| Comment(0) | TrackBack(0) | 技術TIPS/まとめ