l'essentiel est invisible pour les yeux

Thursday, August 31, 2006

PHPのevalは遅くない (require vs eval)

今日の昼飯は、とんかつ 武信分点行ってきました。
ロースカツ膳 竹を食べて、かにクリームコロッケ単品を一つで注文。値段は、1600円ほど。
米油であげているからか、ジューシュにかりっとあがっていて、食べた後も意外とあっさり。肉厚でなかなか美味でした。

夜は焼酎と日本酒を取り揃えているみたいなので、焼酎を飲みながら特選醤油ダレとすだちでとんかつを食べてみたい。


最近、理由あってRuby, PHP, Javascript3つを同時に書かなければいけなくて頭が混乱しそう。

PHPのスクリプトをWEBサーバ経由で返すサーバからPHPファイルを取得し、キャッシュし(ファイルを作成して)実行するプログラムを書いてると、ふと気になった。

* ファイル作ってファイルシステム経由で読み込むよりも共有メモリでやるほうが断然早いよな。
* 共有メモリ上のデータをevalするほうが遅いか?ファイルシステムから読み込む方が遅いか?

ファイルシステムとか使うよりもダイナミックにロードする方がカッコイイが速度が気になる。。

で、作った。

SPEC
* eAcceleratorが入っている場合には共有メモリつかいますよ。
* 入っていない場合には、ファイルシステム使いますよ。
* 作成途中のファイルにアクセスが来ても不整合なファイルにアクセスすることが無いように、ロックかけるか作成してからリネームしましょう。
* ソースコード中の最初にある定数宣言でスクリプトレポジトリを設定してくださいよ。

ソースコード


// ScriptLoaderに関する設定
define('SC_UPDATE_SERVER_PATH', 'http://yourserver/');
define('SC_CACHE_DIR', 'caches/');
define('SC_CACHE_EXPIRED_MINUTES', 10);

/**
* ネットワーク越しにスクリプトをロードしキャッシュする
*/
class ScriptCache
{
/* 強制的にネットワークから読み込む */
var $_forceLoad = false;

function ScriptCache()
{
$this->_enableEAccelerator = ! is_callable("eaccelerator_load");
}

/**
* ファイルを読み込む
* キャッシュが有効な場合はキャッシュを読み込む
*
* @access public
* @param $file string 読み込むファイル名
*/
function fetch($file, $force_load=false)
{
$cach_file_name = $this->_getCachedFileName($file);
if($this->_enableEAccelerator) {
$cached_contents = eaccelerator_get($file);
if(!$cached_contents || $force_load) $this->_load($file);
eval($cached_contents);
} else {
if($force_load || !file_exists($cach_file_name) || (mktime() - filemtime($cach_file_name) > SC_CACHE_EXPIRED_MINUTES * 60)) $this->_load($file);
require_once $cach_file_name;
}
}

/**
* キャッシュファイルを削除する
*
* @access public
* @param $file string ファイル名
*/
function clear($file)
{
$cach_file_name = $this->_getCachedFileName($file);
if($this->_enableEAccelerator) {
eaccelerator_rm($file);
} else {
file_exists($cach_file_name) && unlink($cach_file_name);
}
}

/**
* ガベージコレクション
* 不要となった共有メモリ領域の開放
*/
function gc()
{
if($this->_enableEAccelerator) eaccelerator_gc();
}

/**
* ネットワーク経由でファイルを読み込みキャッシュする。
*
* @param $file string ファイル名
* @return boolean 失敗したらfalse
*/
function _load($file)
{
if($res = $this->_networkFetch(SC_UPDATE_SERVER_PATH. $file)) {
$tmp_filename = tempnam('','');
$cache_file_name = $this->_getCachedFileName($file);
if($this->_enableEAccelerator) {
eaccelerator_lock($file);
eaccelerator_put($file, preg_replace('/<\?(php:?)?|\?>/ims', '', $res['body']), SC_CACHE_EXPIRED_MINUTES * 60);
eaccelerator_unlock($file);
} else {
if($fp = fopen($tmp_filename, 'w')) {
if(fwrite($fp, $res['body']) === FALSE) {
return false;
}
fclose($fp);
rename($tmp_filename, $cache_file_name);
chmod($cache_file_name, 0644);
}
}
return true;
} else {
return false;
}
}

/**
* キャッシュファイル名の取得
*
* @access private
* @param $file string ファイル名
* @return string キャッシュファイル名
*/
function _getCachedFileName($file)
{
$cwd = getcwd();
return $cwd. '/'. SC_CACHE_DIR. $file;
}

function _networkFetch($url, $initheaders=array(), $timeout=10, $limit=10)
{
!is_array($url) && ($aUrl = parse_url($url));
$client =& new HTTP_Client();
$client->setDefaultHeader($initheaders);
$client->setMaxRedirects($limit);
$client->get($url, null, false);
if(PEAR::isError($res = $client->currentResponse())) {
return false;
}
return $res;
}
}
?>

で早速ベンチとってみた。

キャッシュせずに常にネットワーク上から読み込む。

ソースコード

start();
$sl->fetch('test.php', true);
$timer->stop();
ob_end_clean();

print '<pre>';
print_r($timer->getOutput());
print '</pre>';

$sl->gc();
?>

time indexex time%
Start1157032411.98688100-0.00%
Stop1157032412.023001000.036120100.00%
total-0.036120100.00%


ファイルシステムでキャッシュしてrequire
キャッシュタイプを切り替えるオプションは用意していないので、

$this->_enableEAccelerator = ! is_callable("eaccelerator_load");

のようにしてファイルキャッシュするようにする。


time indexex time%
Start1157032411.98688100-0.00%
Stop1157032412.023001000.036120100.00%
total-0.036120100.00%

で、次。



eAcceraletaor APIを使いメモリ上にキャッシュしてevalする。

time indexex time%
Start1157033202.28823800-0.00%
Stop1157033202.290016000.001778100.00%
total-0.001778100.00%

結果はファイルシステム経由で読み込んだ場合とほとんど同じ。


結論
PHPのevalは遅くない。
eAcceralerator API使ったが思ったほどパフォーマンスが出なかったのが気になる。

今日の昼飯は特選醤油トンカツ

東京-京都を交互に行き来する生活も4ヶ月目。
東京は、知り合いや友達からの情報があらかじめないと、美味しいものを食べれる店にたどりつくのが難しいと聞いていたのですが、納得。

今日の昼はとんかつ 武信分店に行ってきます。
すだちで食べる、特性醤油とんかつがうまそう。。

後、せもりなという国分寺のパスタが気になる。。
HPが無いのに数々のブログで紹介されていて、高い評価を受けている。
今週末あたり行ってみようかな。

せもりな
紹介されているブログ
http://usalog.cocolog-nifty.com/usalog/2004/09/post_28.html
http://oisiine.exblog.jp/3485243/

Tuesday, August 22, 2006

VMWareでホストOSと時刻の同期

備忘録。簡単な方法。


$ cd /usr/local/src/
# mkdir vmw
# wget http://chitchat.at.infoseek.co.jp/vmware/vmw.c http://chitchat.at.infoseek.co.jp/vmware/vmw_door.s
# gcc -O -DHAVE_CLOCK_SETTIME -o vmw vmw.c vmw_door.s -lrt
# ./vmw -t
# ln -s /usr/local/src/vmw/vmw /usr/bin/vmw
# vim /etc/crontab
0-59 * * * * root vmw -t 2>&1 /dev/null
を追加

Saturday, August 19, 2006

CSS3について覚え書き

CSS3についてメモ。

Border 関連のプロパティ

15. The 'border-color' properties
グラデーションの掛かったボーダーを実現する。

対応ブラウザ: Mozilla
div.box {
height: 15px;
padding: 10px;
width: 200px;
text-align: center;
}
div.border-color {
border: 10px solid #000;
-moz-border-bottom-colors: #000000 #003F09 #005F0D #008F13 #00CF1C #00EF20 #3FFF59 #6FFF82 #AFFFBA #DFFFE3;
-moz-border-top-colors: #000000 #003F09 #005F0D #008F13 #00CF1C #00EF20 #3FFF59 #6FFF82 #AFFFBA #DFFFE3;
-moz-border-left-colors: #000000 #003F09 #005F0D #008F13 #00CF1C #00EF20 #3FFF59 #6FFF82 #AFFFBA #DFFFE3;
-moz-border-right-colors: #000000 #003F09 #005F0D #008F13 #00CF1C #00EF20 #3FFF59 #6FFF82 #AFFFBA #DFFFE3;
}


-moz-border-<position>-colors:
プロパティでボーダーの色を複数指定できる。順に色合いを変えることでグラーデーション調の線を引くことが可能。


<div class="box border-color">
UIEvolution Japan.
</div>

サンプル

19. The 'border-radius' properties

CSSで角を丸くする

対応ブラウザ: Mozilla, Webkit 最新版

div.border-radius {
border:1px solid #000;
/* Mozilla */
-moz-border-radius-topleft: 10px;
-moz-border-radius-topright: 10px;
-moz-border-radius-bottomleft: 10px;
-moz-border-radius-bottomright: 10px;

/* Safari */
-webkit-border-left-radius: 10px;
-webkit-border-right-radius: 10px;
-webkit-border-top-radius: 10px;
-webkit-border-bottom-radius: 10px;
}


<div class="box border-radius">
UIEvolution Japan.
</div>

サンプル

3.4.1 The 'border-image' properties
通常のボーダーの変わりに画像を使用することが出来る。
コーナーと、コーナーとコーナーを結ぶ線の画像をそれぞれ指定することが出来る。

border-image: uri;
  • border-top-image
  • border-right-image
  • border-left-image
  • border-bottom-image
border-corner-image: uri;
  • border-top-left-image
  • border-top-right-image
  • border-bottom-left-image
  • border-bottom-bottom-image
ボーダー・コーナーともに個別に指定することが出来る。

最新版のWebkitでは、
-webkit-border-image:
でサポートしている様子。

3.26. Media Queries
Media Queryを使用すればより細かくデバイスに適用するスタイルを選択することが出来る。
media属性の指定とスタイルに対する指定でスタイルを適用するかどうか判定する。

対応ブラウザ: Operaと最新版のWebkit


/* Media query */
@media all and (min-width:650px){
div.box2#min-width {
background-color: #0300FF;
}
}
@media all and (max-width:1000px){
div.box2#max-width {
background-color: #0300FF;
}
}



<div class="box2 media-query" id="min-width">
650pxより大きいと青色
</div>
<div class="box2 media-query" id="max-width">
1000pxより小さいと青色
</div>


OperaとWebkitでウインドサイズを色々変えて表示してみてください。
サンプル

このMedia Queryを使用すれば、PCと携帯両方で動作するHPを簡単に作ることが出来そう。
スタイル属性にはディスプレイのサイズ・ディスプレイの高さ・ディスプレイの色の濃さを指定できる。
To describe in more detail what type of devices a style sheet applies to, this document proposes media queries. A media query consists of a media type and one or more expressions to limit the scope of a certain style sheet. Among the proposed media features that can be used in expressions are "width", "height" (size of the display), and "color" (color depth of the display).
とWorking Draft中に書かれている。

CSS3 module: Multi-column layout
対応ブラウザ: Mozillaのみ

3カラムレイアウトや2カラムレイアウトを簡単に作ることが出来ます。

div.multi-column{
-moz-column-with: 100px;
-moz-column-gap: 1em;
-moz-column-count: 3;
}


<div class="multi-column">In preparation for the release of Mozilla
Firefox 1.5 Beta 1, the tree will be locked down tonight at 11:59pm Pacific
Daylight Time (UTC -0700). After this point, no more checkins will be accepted
for Firefox 1.5 Beta 1, which is set for release on Thursday.

In preparation for the release of Mozilla
Firefox 1.5 Beta 1, the tree will be locked down tonight at 11:59pm Pacific
Daylight Time (UTC -0700). After this point, no more checkins will be accepted
for Firefox 1.5 Beta 1, which is set for release on Thursday.
</div>

一つのカラムの幅を100px、カラム間の空きを1em, カラム数を3つに指定します。

サンプル


7. Box Model addition
長い間、多くのWeb開発者やデザイナが苦しめられてきたボックスモデルの違い。
CSS2.1勧告のボックスモデルでは内容領域の高さと幅をあらわしますが、IEなどの一部のブラウザはボーダーやパディングも含めた領域を高さと幅とします。
CSS3で勧告されている、box-sizingプロパティは、どちらのボックスモデルを適用するかを指定することが出来ます。

box-sizing: content-box | border-box
content-box
要素の高さ(height)と幅(width)はCSS2.1勧告の視覚整形モデルに従う。指定された高さと幅は内容領域の高さと幅に適用される。パディングと高さは内容領域の外側に描かれる。

border-box
指定した幅と高さは、パディングとボーダーを含めた値になる。

9.1. 'resize' property
対応ブラウザ: 最新版のWebkitのみ

CSSのみで要素のリサイズを可能にします。
resize: both | horizontal | vertical;
bothを指定すると両方向にリサイズ可能。
horizontalを指定すると水平方向にリサイズ可能。
verticalを指定すると垂直方向にリサイズ可能。

サンプル

9.8. Text shadows: the 'text-shadow' property
対応ブラウザ: 最新版のWebkitのみ

Photoshopで作成できるような影付き文字の簡易版をCSSだけで作成することが出来ます。

text-shadow: 2px 2px 2px #ff0000;


CSS2から存在するが現在実装されているブラウザはWebkitだけなようです。
上記の設定では、右側に影を2px, 下側に影を2px、ぼかしを2pxで色は赤色。

サンプル


6.3.2. Substring matching attribute selectors
部分文字列でマッチ可能なセレクタが追加される。

[att^=val]
attがvalから始まる要素
[att$=val]
attがvalで終わる要素
[att*=val]
attが少なくとも一回はvalを含む要素

拡張子が.htmlのアンカ要素のみ取得するセレクタ
a[href$=".html"]


疲れたので、とりあえずこのへんで。