2010年8月28日土曜日

lighttpd で suexec

lighttpdやらnginxやら、
「apache2の代替」もかなり出揃ってますが、
今だに、apache2でしか出来ないものが幾つかあります。

代表的になのは、次の2点でしょう。
  • suexec
  • webdav+subversion

後者については、
未だにsubversionを使う方が間違ってるので、
「別にmercurialで、hgwebdir.cgiでいいんじゃね?」なので、
それで解決。

肝心の前者は
CGIをサポートしているlighttpdなら、やりようはあります。
#fast-cgiでは無理?!

って利いた風なことを書いてますが、カンニングしました。

http://d.hatena.ne.jp/ikasam_a/20060817/1155826140

と言うわけで、てっとり速く、全自動スクリプトを書きました。

http://gist.github.com/519592

要するにこういうことです。

気の短い人はこちらへ
http://gist.github.com/raw/519592/723035cd81d075e6ab743ba0e7eacf4fd3c7b435/install.sh

ubuntu lucid のsymlinks

unix/linuxのシンボリックリンクは色々便利ですが、
リンク先ファイルの存在を保証しないので、
たまに切れてたりします。

symlinksは、それをメンテナンスするパッケージですが、
どうもlucid(10.04)に入っているモノはバグってるっぽい。

色々調べて見ると、karmic(9.10)収録のsymlinks 1.2-5は正常に動くので、
ダウングレードすることにしました。

ダウングレードの方法は色々ありますが、
手動でdebパッケージを落として来て、
インストールする方法。

まあ、ようするにこうします。

https://gist.github.com/8ac58ebd2036127cfd15

気の短い人は、こちらへ

https://gist.github.com/raw/8ac58ebd2036127cfd15/b77be76f532636b93355edbc5b631bc091c155c0/gistfile1.sh

2010年8月27日金曜日

youtube-dl 日本語版

職業プログラマで、自宅あるいは会社のPCに、
linux入れてます、って変人は少なくないと思います。
いやそういう事にしてください。

linuxであれば、youtubeの動画の保存には、
当然youtube-dlを使ってますよね。
いやそういう事にしてください。
http://bitbucket.org/rg3/youtube-dl/wiki/Home

コマンドラインのダウンローダは数あれど、
ファイル名に、youtubeの動画idを付けてくれるのは意外と少ないです。
#動画のページタイトルからタイトルを作ってくれるのは当たり前。
デフォルトで、というべきか?

ところが、残念なことに、日本語のファイル名を作ってくれません。
日本語部分というか、黄色人種の国の文字がバッサリ落ちます。
まあ作者は英語圏の人っぽいので、まあ読めない文字でファイル作られても楽しくはないでしょう。

仕方がないので、個人的に日本語パッチ当てて使ってましたが、
bitbucketでは、他人のフンドシで相撲がとれる(fork)らしい。

それって。本家の人はどう思うんだろう?
そしたら居るわ居るわ派生バージョン。
http://bitbucket.org/rg3/youtube-dl/descendants

はい、forkさせていただきました。
https://bitbucket.org/kamawanu/youtube-dl-japanesefilename
mercurialだっつーのも活けてますね。
#gist/githubはあっちはあっちで使ってますが、gitには微妙に馴染めません。

と思っていたら、githubに引っ越しちゃってました。

やっぱりforkするわけですが

2010年8月19日木曜日

PHPが目指すもの

ここ最近、付け焼き刃的アンチPHP振りが恥ずかしくなってきたので、
今一度初心に帰って、PHPの目指すものを考察してみたいと思います。

筆者は、web業界としては古株で、それこそ「perlでCGI掲示板」からやってます。
pythonは既に存在していた筈ですが、日本ではまったく無名でしたね。

perlの頃は

実装については、CGI非専用言語なので、HTTPレスポンスヘッダを
自分で吐かなければなりません。これは初心者にはちょっと辛いかも。

また、レスポンスヘッダを作成するまえにエラーで落ちたりすると、
エラーメッセージがブラウザまで返って来ません。
これもデバッグが面倒でした。suexecやってたりすると更に面倒。

更にperlで中規模以上の開発をやろうとすると、問題になるのがCPAN。
CPAN自身が問題というよりは、大体稼働場所が「レンタルサーバ」なので、
新しいCPANは入れさせてもらえない。という事に成りがちです。

そこから行けば、PHPは天国です。

スクリプトでエラーが出ても、画面にペロっとメッセージが出てくれます。
厳密には、その設定はデフォルトoffだったりするのですが。

application/x-urlencodeの場合、ブラウザから送ってきた筈のデータは
既に「$_REQUESTに入ってる」。これは単純に、楽ちんです。

何処のレンタルサーバでも、概ね「全部入り」なので、
開発環境と稼働環境の統一に、あまり悩まなくて済みます。

また言語自体は、プラットフォーム依存は、あまり有りません。
#厳密には、アーキテクチャ依存はあったりしますが。

「サーバはWindows 20XX Serverです」とか言われると、ぶっちゃけ血の気が引きますが、
apache2とphpをインストールするだけで、
動いてくれるのは、軽量言語としては貴重です。

#サーバが、IISで、ActivePerlを入れて。とか。考えたくない。


忘れがちなのが、セッション処理を内蔵していること。筆者はperlでクッキーセッションを自力実装して、バグった事があります。クッキーを受け取らないブラウザでは、複数の人間が同じデータを参照してしまうというバグ。サービスサイトでは恐ろしい限りです。


総評として、

「perlより、そこそこ楽にweb開発をする言語」としては、優秀である。

とは言えましょう。

しかし、「その他」が駄目だった。

名前空間が有りません。
#perlには有ったのに。何で取っちゃったのか?

無いだけならまだよいのだが、前述の「全部入り」だと、
それだけ名前空間を食いつぶされるということでもあります。

array_*とか、ダサい関数名なら幾ら使ってもらっても構いませんが、
http://jp2.php.net/manual/ja/book.array.php
DirectoryIteratorとか、付けたくなるクラス名ですよね。
http://jp2.php.net/manual/ja/class.directoryiterator.php
#実際、php4から5の時に、それで動かなくなったスクリプトが有ります。

5.3で、ようやく名前空間を実装しましたが、
名前空間の区切り記号がバックスラッシュです。
http://jp.php.net/manual/ja/language.namespaces.nested.php
「サブ名前空間」?
名前空間に「サブ」ってどういうこと?
これ正直、気持ち悪いのですが。

#と思ったら、意外と受け入れられてるらしく、
http://blog.asial.co.jp/658

組み込み関数で、戻り値に整数型と論理型が混在してます。
混在するだけならまだ良いのですが、統一性がありません。
http://jp2.php.net/strpos
http://jp2.php.net/manual/ja/function.preg-match.php
falseの使い方に注目。

本質的な問題として、
バージョンアップで何かしら言語を拡張しようというときに、
「組み込みクラスを増やす」「組み込み関数を増やす」。それはまだいいのですが。
その他は「連想配列でなんとかする」という凄いポリシーを感じます。

この辺りの象徴は、call_user_funcに或る。と言えるでしょう。
http://jp2.php.net/manual/ja/function.call-user-func.php
1番めの引数には、「関数名」を「文字列」で渡します。

これだけでも気持ち悪いのですが、じゃあオブジェクトの場合はどうするのか?
array($classname, $methodname) これを入れろと言ってます。
前者は概ね、& $thisと書くべきでしょう。

$return = call_user_func( array( & $this, "method1" ), $param1 )

ナニコレ。気持ち悪いこの上なし。

総論に追加しなければなりません

しかし、中規模以上の開発に使うには難あり

理由は主に前述の通りですが、

一番の理由が名前空間が無いので、人間が「名前空間エミュレーションしている」。

ディレクトリ名はクラス名に前置するのが流行ってます。
Zend_Db_Table_Abstractとか。しかしこんなのは、完全に対処療法です。

必然、プロジェクトファイル群の構成として
長いクラス名と、
深いディレクトリ構造に、
大量の細かいファイル群を扱わなければなりません。

人間が手動で扱うのには無理があります。

統合環境を使わなければやってられません。

「お気楽言語であった筈」のPHPに、
「Javaの面倒くささ」を持ち込まざるを得なくなってしまったという。
本末転倒と言うか、ミイラ取りがミイラになるというか?
アレJavaがミイラ?

強調しておきますが、筆者は、統合環境にもJavaにも好意的ではあります。
Javaは「中規模未満の開発に使うには難あり」だと思ってますけどね。

2010年8月15日日曜日

もうmongodbでいいんじゃね?

出稼ぎ先の都合で、key value storeのNoSQLを検討する必要が出てきました。

KVSで有名なのは、apache cassandraですが、
http://cassandra.apache.org/
資料を眺めて残念に思ったのが、データベーススキーマの定義がxmlなこと。
http://wiki.apache.org/cassandra/StorageConfiguration

#どうも、javaな人々は、「xmlの設定」に抵抗が無くてアレですが、
#筆者は、人間に優しくない「設定ファイル」は大反対です。
#eclipseがあるからヘッチャラだぜとか、それは何か違うと思う。
#個人的にはもう全部yamlにしようぜと思っています
http://www.yaml.org/spec/1.2/spec.html
# 2011年11月現在では、定義ファイルは、yamlになってるっぽい。そうだよね。普通はそこに落ち着くでしょう。

それと、設置にはcassandra自身の他にhadoopが必要で、
ぶっちゃけ面倒臭そう。で、筆者はその辺りで心が折れました。

とは言え、
google datastoreで言うところのreferenceproperty入れ子、の様な事も
出来そうな感じなので、今回の「都合」より複雑なニーズであれば
考慮する必要はありそうです。

他の選択肢は色々ありますが、

couchdbは、
http://couchdb.apache.org/
「httpでイイヨ」で売っているのが微妙に引っかかりました。
まあ改めてポートを開けなくて良いのは助かるけど、
実装全体としては、それだけでは助からないので。

couchの語源は、ソファです。http://en.wikipedia.org/wiki/Couch
だらだらしようぜ。って意味らしいけど。
どうなんだこれ。

そして、最後の選択肢、mongodb
いやもうこれでいいんじゃね?
#「最後」じゃネエだろ、って突っ込みは間に合ってます
http://www.mongodb.org/

一つは内蔵のクエリ言語が、javascriptであること。
クエリに関数をねじこむと、mapreduceしてくれる。ってんじゃありませんか。
http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-ShellExample1
頼もしくね?
いや、今回の「都合」はそこまで要らない筈ではありますが。

もう一つは、起動が簡単過ぎること。

最低限のコマンドラインは、dbpath。意味はご想像通り。
しかもデフォルト値に合わせるんなら設定要りません。

mongod自身のメッセージ表示は、止めた方が良いかも知れません。
限界性能レベルでは、メッセージ出力のI/Oがネックになったりとかするので。

しかも、テーブルのスキーマ定義は不要です。
コマンドライン(?)では、JSONのオブジェクトを受け付けます。
もうそれで済んでしまう話。
しかも、オブジェクトのプロパティに対して、ちゃんとクエリを掛けられます。
PHP等の実装では、多段連想配列を渡します。まあ理屈は一緒なんだが。

しかして、その限界性能レベルでは、実に馬鹿っ速い。
2秒ぐらいで、10万レコードがスルっと入ります。
DBネックの心配は、当面要らないでしょうこれなら。

core i5でした。まあ実施自体は簡単なんで、皆さんもお試し頂ければよろしいかと。

mongodbの「スケール」は、「シャーディング」或いは「レプリケーション」です。

前者は試してませんが、正規のサーバの前段に、シャーディング管理サーバを挟む形態。
http://www.mongodb.org/display/DOCS/Sharding+Introduction

レプリケーションは設定が簡単しかも動作が速い。


コマンドラインで、レプリケーション元サーバのIP等を指定するだけです。
http://www.mongodb.org/display/DOCS/Replication

ubuntu 10.04には一応は標準パッケージがあるので、
apt-get出来ますが、何故かlibmozjs.soのリンクに失敗しますが、
仕方がないので筆者はxulrunnerのモノをld.so.conf.dに書き足してます。

ubuntuのパッケージには、当然/etc/mongodbが有りますが、
前述の通り、基本的にコマンドラインで事足ります。

2010年8月14日土曜日

「速い言語」とは何なのか?

先日、PHPは遅い的なエントリを書いたばかりですが、

プログラミング業界にとっては、
「書きやすく、しかも何を処理しても速い」言語が永遠のテーマです。
実際にはそれほど上手い話はあまり有りません。

多数の言語が存在していることが、
逆にその証明になってるでしょう。

優れた言語であっても、不得意分野が必ずあり、
そのための言語が必ず産まれます。

似て非なる話で、MS Windowsプログラムでは、
古来ではwin32 apiを直接呼んでいたりしてましたが、
ある時から、MFCとか言い出しました。
GUIの「複雑な実装」には「オブジェクト指向」の考え方を取り入れるしかなかったからです。と、筆者は考えていますが。
更にそれでもダメで、C#とか言い出した。まあC#の言語としての評判は悪くなさそうですが。

「何を処理しても速い言語」はどうやって探すのか?

言語の実効速度の比較には、「ベンチマークテスト」がありますが、それをやっているサイトは、多数あります。

http://shootout.alioth.debian.org/u32q/which-programming-languages-are-fastest.php

大抵は、「Cが爆速で、スクリプト言語は激遅」みたいな結論に落ち着きがちです。

その中身は、「エラトスネスの篩」だったりとか。

いや、悪いって言うんじゃなくて、
言語の一部の性能だけを見ているのは確かですね。

例えば、前述のエラトスネスの篩だと、
多回転ループ、長配列の処理ってことになりますが、
果たして、実際の実装で、そういうケースが有るのかどうか?

って言うか、ネエよ!
受注開発で「エラトスネスの篩を作ってください」とかネエよ!

言語の「設計思想ベンチマーク」とでも言うべきものなのかも知れません。

ドコゾの何かのアプリケーションで、ベンチマークモードとかあるとか聞いたような。コンパイラだったかな?

もっと「実際の摘要に即したベンチマークテスト」が必要なのではないでしょうか。

「速い言語」を探して何をするのかというと、
最近ではもう大体webアプリケーションサーバでしょう。
#一昔前はWindows MFC一択でした。いい時代です。

じゃあ何を使えば良いのか?

C/C++で書くのが「速い」のは判りきってる事ですが、
それは低級言語だからであり、コンパイラだからでも有ります。

しかしwebアプリケーションをC/C++で書く、
なんて話は聞いたことがありません。

webアプリケーションの処理は、
文字列を切ったり貼ったりが非常に多く、
それはC/C++では、不得意分野だからです。
所詮は、言語はプログラムの手段、道具なのですから、
適材適所でしかるべきです。

そして、何やら、爆速テンプレートエンジンが有るって言うじゃありませんが。

http://www.kuwata-lab.com/tenjin/
名前からして日本人の作かな?と思いましたが、
英語ページしかありません。

#テンプレートエンジンだから、Tenjin?
#日本人のセンスだよなあ。

テンプレートエンジンの実装として、馬鹿正直に考えると、
大抵は、◯◯クラスを定義して、
テンプレート文字列を切ったり貼ったりする訳ですが、

このTenjinとやらは、そうではないらしい。

内部では、完全な単体スクリプトに変換してしまうらしい。
http://www.kuwata-lab.com/tenjin/phptenjin-examples.html
軽量言語のみサポートしているのもそういう事なのでしょう。

バイトコンパイラの性能頼みですが、実際速いらしい。
http://www.kuwata-lab.com/tenjin/img/fig01.png

比較対象が、不利な実装になってる可能性は否定できませんが、
Tenjin自身がそれだけ速いのなら、使ってみようか、
という気にもなります。

似たようなコンセプトで、JavaにはJSPが有る訳ですが、
残念ながらJSPが遅いのは有名です。
http://d.hatena.ne.jp/kwatch/20100603/1275524286
何故か、を危うく書こうとしてしまいましたが、
知ったかぶりが露呈するので辞めておこう。

2010年8月10日火曜日

グーグル画像検索が、快適化

おもむろにグーグル画像検索を使ってみたら、
またパワーアップしてましたね。
しかも何で気づかなかったかというと、
Firefox専用らしい! Google Chromeでは稼働しません。



サムネイルの密度が上がって、ページ切り替え無しの上下スクロール。
グーグルマップのアレの延長線上にある技術でしょう。
iPhone等では、フリックでめくれるので、
むしろPC版でのスクロール実装は遅かったぐらい。

スクロールが差し掛かると、画像のロードをするlazyloadの採用。
なので、絶望的なスクロール範囲の割に、PCのメモリ使用は控えめな筈。

カーソルが重なると、ウニョンと拡大、さらにそれを選ぶと、
ページに飛びますが、とんだ先では、本来のページが背景に隠れて、
画像を、勝手にライトボックス表示。

2010年8月8日日曜日

mercurialとsubversion file:の実行時間測定

出稼ぎ先で、subversionに悩まされてます。

悩んでいる理由はさて置き、とりあえず「遅い」です。
mercurialに慣れた筆者には、20倍は遅く感じます。

具体的に、どの程度遅いのか、測って見ました。

結論から言うと、subversionはローカルで動かしても、
mercurialの2〜3倍遅い。ということに成りそうです。

Cで書いてある筈のsubversionが
pythonで書いてあるmercurialより遅いってどうよ?

普通にベンチマークすると、真逆になる話ですね。

速度に影響するのは、実装言語じゃない。
データ構造とアルゴリズムであるという。
好例ですね。

/usr/bin/timeで簡単に測ってみると、
subversionは、sysの時間が長めに見えます。
disk IOがネックになってる?

カーネルソースは、バージョン管理の「具」としては、
上品な部類だと思います。
これで、巨大なバイナリやらも詰め込んだらどうなることやら。

linuxカーネル2.6.35のソース 66MB

tarの展開
real 1m2.495s
user 0m43.451s

hg init
hg add
real 0m9.517s
user 0m1.940s

hg commit
real 1m12.223s
user 0m54.771s
#更新数 33316

hg clone
real 0m44.199s
user 0m22.597s

svn import linux-2.6.35 file://*/SVFS -q
real 3m47.385s
user 1m7.488s
sys 0m26.194s

svn co file://$PWD/TEST-SVFS linux-co -q
real 2m13.232s
user 0m47.135s
sys 0m18.765s