2009年1月13日火曜日

Google Chromeが速いわけ: スピード狂のあり方

@ITにGoogleのブラウザ「Chrome」に対する開発者のスピード狂ぶりを綴った記事が出ていました。

この記事によると、Webサービスにおいては0.5秒遅いだけでユーザが離れていくそうです。その教訓から、Chromeには徹底したスピードへのこだわりを終結させており、その結果としてあの素晴らしいレスポンスが得られるようになったわけだそうです(私が使っているような低速なPCではそれほど激早というわけではないですが)。

個人的にはプロセス分離やドメイン先読みはやりすぎなような気がしますが、他のブラウザがやらない(できない)ことをしている、という点では面白いと思います。

開発者は皆、多かれ少なかれスピード狂です。私はそれほどスピード狂ではないですが、応答性を高めるためにスレッドを分けるとか、ファイルからのI/Oを極力減らすとか、データの先読みをする、という点は常に気をつけるようにしています。

一方でメモリ使用量も抑えるように色々考えています。スピードとメモリ使用量はトレードオフですからね。例えば10万パケット入っているキャプチャファイルに対して、全てのパケットの開始位置(uint)をリストにするだけで400KB必要です。タイムスタンプと発着IP/Portも一緒に保存したら3MBぐらい必要になります。

スピードのためにメモリを大量確保するのか、それともスピードを犠牲にしてメモリ使用量を抑えるのか、もしくは両方とも折り合いのつく着地点を探るのか、開発者はいつでも葛藤しています。Googleの中の人は相当苦労したと思います。それともノウハウたくさん持っているからそれほど苦労せずに見通しが立つのでしょうかね。うらやましい。。。

2009年1月1日木曜日

[WireWhale]激早!! FileStreamのPosition、Length→自前で保持

今までキャプチャファイルの読み込みはFileStreamからPositionプロパティを使ってせっせと読み出し、Lengthプロパティの位置まで来たら止める、という方法をとってきました。これだと50MBのキャプチャファイルを読み出すのに大体10秒ぐらいかかっていました。

Wireshark(というかcapinfo.exe)でキャプチャ情報を読み出すのも大体それぐらいかかっているので、それが普通かなと思っていました。が1ファイル開くのに10秒も待っていられない! 何とかならないものかと試行錯誤していました。

そんな中、CodeProjectにFast Binary File Reading with C#という、ストリームの読み込みの手法毎の性能比較の記事があったの でWireWhaleもチューニングしてみました。具体的には、PositionLengthプロパティの使用を極力減らし、値は変数で保持、Positionを移動するときはSeekを使うようにしてみました。

結果、、、びっくり!!! 何と50MBのキャプチャを開くのに5秒かからなくなりました!!! プロパティ内で何してるんでしょうね!?

やっぱりこういう細かい調整が性能を大きく左右するんですね。とても参考になりました。

参考
Fast Binary File Reading with C#

2008年12月29日月曜日

Web2.0(Ajax)時代の標準文字コードはUTF-8?

今から3年ぐらい前、Web2.0なんて言葉が出始め、Ajaxはまさに黎明期、Google Mapsとかにみんな驚き、JavaScriptが威厳を取り戻しつつあった時代がありました(そんなに昔の話じゃないですよ。3年前の話ですよ)。私もご多分にもれずそれに感化され、卒研では意味もなくXHTML+JavaScript+PHPをAjaxでつないでいました。

その頃は若かった(?)ため、HTMLに当たり前のようにUTF-8を使い、サーバとのやり取りもすべてUTF-8で行っていました。若い時は「XMLはUTF-8がいい」なんて聞いたら、それ以外を使うのはすべて悪であるかのような錯覚をしていたので、特に違和感もありませんでした。

しかしそれから3年が過ぎ、ふと別件でAjaxについて(今更)調べる中で「decodeURIComponentはUTF-8しかデコードできない」という事実を知り驚きました。それってつまり、HTMLもUTF-8にしなきゃならないってこと?

と思ったら、なぜかデコード後の文字列は、HTML自体がShift_JISの場合はShift_JISになる! どういうこと?

そもそもdecodeURIComponentにUTF-8以外の文字列をエンコードした文字列を渡すと、「error: malformed URI sequence」になってしまいます。UTF-8以外はデコードできないからですね。それを回避するためにサーバはresponseTextに常にUTF-8文字列が返るように実装しなければなりません。イマドキそんな制限ないっすよ~

decodeURIComponentはRFC2396に準拠しているんですってね。そこにUTF-8以外は認めないとか書いてあるんでしょうか。そのうち勉強します。

2008年12月22日月曜日

CDに対する愛着の薄れ

大塚愛さんの「Love Letter」を購入しました。大塚さんのステキな笑顔のアップというインパクトのあるジャケットです。グッときます。ドキッとします。:*)

思えば昔はCDを1枚買うごとに、CDプレーヤで再生しつつ歌詞カードをじっと眺め、1曲1曲をかみしめながら目と耳で楽しんでいました。もっと言えば、ジャケットの絵や写真だけでも友達と一緒にいい悪い、好きだ嫌いだと話したものです(そんなに昔の話でもないですが)。CDがバカ売れた時代(そう、小室全盛期の頃です)のようにCDという、音楽ではなく、ものをとてもありがたがる、ということを最近しなくなったなーと感じました。今20~30代の人、そうじゃないですか?

ものとしての価値を上げるため、今はDVDが付いてきたりしますが、それも当たり前になってきて、DVDが付いていること自体は特別感はあまりありません。そしてプロモーションビデオを見ても何かおまけのような感じがして、有難味もだんだん薄れてきた気がします(それでも他に合法的に入手する手段のないプロモーションビデオを見ることができるのはありがたいです)。

ファイル共有ソフト黎明期(今から5、6年前のことです)に「CDが売れなくなった」とレコード会社が騒いだこともありましたが、遅かれ早かれ、音楽が日常により近いものになり、音楽はパソコンやiPodで聞く今のような時代は来たと思います。そしてそれとともに、CDに対する愛着はどんどん薄れ、買ってパソコンでエンコードしたら、あとは棚に並べて背表紙だけが日焼けしてゆくという、何とも寂しい時代になってしまいました。

レコード会社の人、今一度ものとしてのCDを再起させるべく、何かいい案考えてください!

2008年12月7日日曜日

Excelファイルがデファクトであることの障害: プログラムとの親和性の低さ

会社で使っているデータの多くがExcelファイル。これらをプログラム(PHP, Perl等)から利用できれば、作業の多くを自動化できるのにな~と思っています。

「思っています」というのは、色々考えてみましたが、有効な方法が思い当たらないからです。

一番一般的なのはCOMを使ってVBAを外部から使う方法ですが、これはWindowsでしか使えません。そのため、私のPCでは動かすことができますが、みんなに使ってもらうためにサーバに配置する、というようなことはできません(みんなが使えるWindowsサーバがないため)。

PHPやPerlにはそれぞれExcelファイルを操作するためのライブラリが用意されていますが、Excelファイルの作成こそある程度は可能ですが、読み込みは完璧ではないようです。サーバ/クライアントシステムとして、サーバ上でデータ操作をして、最終的な出力をExcelファイルとしてダウンロードさせる、といった使い方はできそうですが、サーバ上のExcelファイルを検索して、最終的な出力をHTMLで行う、という用途には向かないようです

やりたいことはまさに上記の後者の例で、サーバ上にある試験項目表のデータ(100ファイルぐらい)を検索した結果をHTMLで表示する、ということなのです。以前Pukiwikiに検索機能を付けた時は、Pukiwikiの全エントリを全文検索して結果を表示させる、という手法をとり、2,000弱のエントリで問題なく動いるのですが、Excelを100ファイルとなると、ファイルから動的にデータを読み出して処理する、というのは難しそうです。

動的なデータ読み出しができないのなら、静的にデータベースを作るなり、XMLに分解するなりすればいいのですが、ファイルが更新されるたびにデータを作り直さなければならないという問題が出てきます。1日1回だけに制限するにしても、更新するのは結局私なんだろうな、と思うとやっぱり現実的ではない気がしてきます。

Excelファイルでデータを管理すること自体、決して悪いことではないと思うのですが、自動化させる、という点からみると何とも忌々しいものです。

2008年11月30日日曜日

FileStreamのPositionがなぜかずれる

私は開発には .NET Framework 3.5 SP1 を Visual C# 2008 SP1 で使っていますが、その環境のせいか、何のせいか、FileStreamPositionを指定しても、反映されない場合がたまにあります。これが一度出るとはまってしまう。。。そして何が原因か分からないまま、事象は解決する。。。

デバッガでPositionを変更した直後に止めてみて値を見ると、代入している値は確かに目的の値なのに、代入直後にStreamPosition0x0000001cになる。つまり以下のコードだけでアウト

  // set source stream position
  source.Position = 0x5000;

 // read packet ↓ここでデバッガを使ってPositionを見ると0x0000001cになっている
 FramePacket lastPacket = new FramePacket(source);

ちなみにseekを使っても同じ。なぜか入れた値のままにならない。デバッガで値を無理やり書き換えてもすぐに0x0000001cに戻る。なんだこりゃ。。。

メガバイトを超えるファイルを扱う場合、これがうまく動かない場合は致命傷です。試行錯誤を繰り返すと治るのですが、原因がよくわからないのは何とも気持ちが悪い。なんでしょうね。

生まれて初めて小説を買いました

別に特別興味があったわけでもありませんが、CMで見て、ニュースで見て、気になってついつい衝動買いしてしまいました。「ソウ―SAW (角川ホラー文庫) (表紙だけでも結構インパクトあるので気の弱い人は見ないようにしてください)」を。初めてでホラーです。映画のノベライズです。

SAWはシリーズ5まである怖い怖い映画で、最近SAW 5のCMが流れています。ストーリーはJigsaw Killer(ジグソウキラー)と呼ばれる殺人鬼が生きることを粗末にしている人間に命をかけたゲームを強いるというものです。映画はかなりグロいそうです。私は気が弱くDVDを買う勇気はいため、小説にしました。

1と2を買い、半日ぐらいで一気に読みました。読んでみて、一般にSAW1の評価がとても高い理由がよくわかりました。よくありがちな、おどろおどろしいだけ、怖いだけ、の話ではなく、人間の生きることへの執念を実にうまく表現しています。ジグソウの仕掛けるゲームも、ルールがシンプルにして深い。とてもよくできた話でした

興味がある人は読んでみてください。