2010年3月25日木曜日

日本特有のメール作法からメールフォーマットの改訂を希望する

たいして新しい話題でもないのですが、今朝Twitter経由で教えてもらった
マナーのあるメールの書き方 〜宛名は敬称に気を配ろう〜
に驚いたことと、その後1時間ほど歯の治療をしていて、この件について考えるより他にすることが無かったことがあり、ブログにしたためることにしました。

この「マナーお悩み速攻解決」の論点は2つあります。
  •  To, CCなどのアドレスのdisplay-nameには社名や敬称をつけよ
  •  メール本文は、社名・部署名・肩書き+名前で始めよ
ITのようなリベラルな業界にいると、取引先の担当者も「さん」づけだったりするので、後者については違和感があります。つまり、
    日経BP社        → 1行目に社名
    ●事業部        → 2行目に部署名
    編集長 木村太郎 様   → 3行目に肩書き+名前+様
    なんて書くことはなくて、
    木村さん
    で始めるわけです。(私は社名もつけません。面倒だし、間違えると大変だから。「キャノン」とか。)
    とはいえ、「会社に所属する」という意識が強い保守的な業界では、社名・部署名を書くのは納得できるところではあります。

    前者については(自分の中で)賛否があって、「自動的に挿入されたものをなぜわざわざ書き換えないといけないのか」と思う一方、「同僚に『様』がついている一方、取引先が呼び捨てのまま送るのはちょっと・・・」とも思うわけです。

    そもそも大抵のMUAでは、メールの新規作成時には、送信先を記入するコントロール(つまりToフィールド)にキャレットが表示され、返信時には、本文を記入するコントロールにキャレットが表示されます。(今確認したら、Gmailでもそうだった。)つまり、Toフィールドを書き換えるということは、マウスクリックするなり、Shift+Tabを押すなりしてキャレットを動かす必要があるわけで、これは非常に面倒な作業です。

    なぜそこまでして書き換えないといけない(と思われている)のかというと、人の呼び名がその人との関係によって異なるからです。木村太郎さんは「木村さま」だったり「木村さん」だったり「木村」だったり「木村編集長」だったり「パパ」だったり「あなた」だったりするわけです。
    これを、上下関係を重視する日本固有の事情と理解するのは違うと思われます。相手との関係によって呼び名が変わるというのは、多くの国の文化として根付いていると思われます。三國志(というか中国)を読んだときに、「相当親しい関係でないと名前で読んではダメで、普通の人は字(あざな)で呼ばなくてはいけない」と書いてあった気がいます(吉川三国志かな)。Wikipediaによれば、
    その人物が官職に就いた場合は官職名で呼ぶことが優先された(諸葛亮なら「諸葛丞相」。丞相が官職名である)。この場合、親しい間柄以外は、字で呼ぶことは、諱(引用者注:名前のこと)ほどではないにしても少々無礼なこととされていた。
    だそうです。

    "display-name" の成り立ちは「メールアドレスだけだと誰だかわからん」という問題だと推測されるのですが、だとすると、そして「関係によって呼び名は変わる」ことをあわせて考えると、「返信時に "display-name" も自動的にTo, CCフィールドに挿入される」という機能がバグではないかと。もっと言うと、To, CCに"display-name"が書けてしまうのは「仕様のバグ」ではないかと。

    "display-name" が、「t.kimura@example.comというアドレスを使っている私は木村太郎です」というように自分を明示するための機能であるとすれば、To, CCなどの「相手」を示すフィールドに "display-name" を記載する必要はないのです。

    というわけで、メールフォーマットの仕様を改訂して、To, CC, BCCには "addr-spec"(いわゆるメールアドレス)しか書けないようにして、"display-name" はFromとSenderにのみ許すのが良いと思いました。

    だれかRFC書いてくれ。

    2010年3月24日水曜日

    Popup Dictionary: 初めてのFirefox addon

    英語のウェブページを読むときに書かせないのが、goo辞書や英辞郎などのオンライン辞書です。ただ、「調べたい単語を選択」→「別のタブを開く」→「オンライン辞書で検索」→「結果を読む」→「元のタブに戻る」という手順は明らかに非効率です。

    ということで、選択した単語の周辺にポップアップで単語の意味を表示するaddonを作って見ました。Firefox addon初挑戦。

    参考にしたページは、Mozilla Developer CenterのXUL / JavaScript / DOMです。最初に "Setting up an extension development environment" を読んで、環境をセットアップしましょう。

    基本的には、ウェブページの作成と同じです。XUL(HTML)で画面を設計し、Stylesheetで細かくデザインし、JavaScriptで動きをつける、と。異なる点としては、
    • HTMLよりコントロールが豊富なXULが使える
    • ブラウザがFirefoxに限定されたため、ブラウザによるJavaScriptの挙動の違いに悩まされることがなくなった(気がしますが、Linuxでしかテストしてないのでわからない)
    • Cross site XMLHttpRequestが使える
    ぐらいでしょうか。

    困った点は、
    • 何を設定すれば、Firefoxの「ツール」→「アドオン」→「設定」から開くコンフィグダイアログを開けるようになるのか? (答:install.rdfにoptionsURLタグを書く)
    • XULのelementにaddEventListenerしても、event handlerに処理が渡ってこない。(答:いまだわからず。windowにaddEventListenerするという応急処置)
    • "about:config"画面に表示されるデータストア (?) に値を保存するにはどうするのか。(答:Components.classes['@mozilla.org/preferences;1'].getService(Components.interfaces.nsIPrefBranch)で取得できるオブジェクト経由でget/set可能。)
    があります。
    最後のComponents.classes[foo].getService(bar)を使いこなせれば、もっと便利なサービスが利用できそうです。が、ドキュメントが見つけられず。

    ソースコードはgithubに置きました。
    こちらから直接インストールできます。
    Popup Dictionary ( http://www.kwakaku.net/public/popupdictionary.xpi )

    2010年3月20日土曜日

    addr2line(相当)のshared library対応版

    メモリリークを検出するためにmalloc/freeの呼び出しをログに残すようにしました。あとはログを解析して、対応するfreeが無いmallocを見つけ、そのmallocのコールスタックを表示してやればOKです。

    ログには、コールスタック中の各関数のアドレスが記録されているので、これを関数名に変換したいです。「addr2lineでできるだろう」と思っていたら、addr2lineはshared libraryには対応していないことがわかりました。つまり、動的にロードされたライブラリ中の関数名は、addr2lineでは分からないのです。

    既存のツールがあると思うのですが、見つからなかったので自作しました。
    方針は以下のとおり。
    1. 解析したいプロセスのmapsファイル (/proc/[PID]/maps)をコピーしておく。
    2. 問題のアドレスとmapsファイルから、どのshared library(のtext region)に含まれているかを調べる
    3. 該当のshared libraryのsymbol tableを参照して、どの関数かを調べる
    4. 表示する

    これでうまくいかないケースとして、
    • dlopenを使ってdynamic linkしていて、取得したmapsファイルにmemory map情報が残っていない。
    • トランポリンコード
    が考えられますが、かなり稀な状況なので現実的には問題にならないでしょう。
    コードはgithubに置いてあるaddr2sym.rbです。

    「mallocがダメならnewを使えばいいじゃない」

    そこそこの大きさのソフトウェアを作った場合、メモリリークが問題になることがよくあります。(初期にメモリ管理についてしっかり設計し、エンジニアの合意を取れば、テストフェーズでメモリリークを気にすることはなくなるのかもしれませんが、残念ながらそのような素晴らしいプロジェクトを見たことがありません。)
    普通の環境 (i386, amd64, ppc32, ppc64) ではValgrindを使ってメモリリークを検出するのが定石ですが、Valgrindが動かない環境ではどうしよう、という悩みがあります。

    とりあえず、「glibcをdynamic linkして動作するアプリケーション」という仮定で、メモリリークの検出方法を考えました。この仮定はそんなに非現実的ではないはずです。
    方針としては、愚直ですが、
    malloc/freeをすべて記録し、対応するfreeが存在しないmallocを検出する
    となります。

    glibcには、__malloc_hook, __free_hookというフックが存在して、malloc/freeの呼び出しを横取りすることができます。がしかし、__[malloc|free]_hookはstatic変数でして、multi-threadedな環境では普通には使えません。

    "man __malloc_hook"からの抜粋ですが、
    static void
    my_init_hook(void)
    {
        old_malloc_hook = __malloc_hook;
        __malloc_hook = my_malloc_hook;
    }

    static void *
    my_malloc_hook(size_t size, const void *caller)
    {
        void *result;

        /* Restore all old hooks */
        __malloc_hook = old_malloc_hook;

        /* Call recursively */
        result = malloc(size);

        /* Save underlying hooks */
        old_malloc_hook = __malloc_hook;

        /* printf() might call malloc(), so protect it too. */
        printf("malloc(%u) called from %p returns %p\n",
                (unsigned int) size, caller, result);

        /* Restore our own hooks */
        __malloc_hook = my_malloc_hook;

        return result;
    }
    とやると、my_malloc_hookの"Restore all old hooks"の直後に別のスレッドがmallocを呼ぶと、hookされていない生のmallocを呼べてしまいます。
    (my_malloc_hookをrecursive lockで囲ってやれば大丈夫な気がしますが、試してません。)

    hookは何かと問題がありそうなので、hookを当てにせず、malloc/freeを乗っ取る方向で考えます。やりかたはBinary Hacks #61のとおり。

    注意点としては、mallocを乗っとると(当然ながら)glibcのmallocを普通には呼び出せなくので、複雑な事ができなくなります。今回の場合では、要求されたサイズやアロケートされた領域のアドレス、コールスタックなどを、例えばstd::setに記録し、freeが呼び出されたら対応するmallocの記録をstd::setから削除する、ということをやりたいのですが、STLなどは当然のごとく使えないです。
    しょうがないので、必要な情報はすべてファイルに書き出して、後からスクリプトで処理することにしました。ところが、fopen, fputs, fcloseなども使えない(内部でmallocを読んでいる?)ので、open, write, closeを使うことになりました。何という低レベルコーディング・・・。

    ともあれこれで、malloc/freeが呼ばれたときに、要求されたサイズ、アロケートされたアドレス、コールスタックをファイルに書き出すことができました。
    あとは、これを解析すればリーク箇所(対応するfreeが存在しないmalloc)を検出することができます。

    ソースコードは、githubにアップしてみました。

    なお、タイトルと本文とは(ほとんど)関係ありませんので、あしからず。

    2010年3月5日金曜日

    トレーディング収益1億ドル超の日数の比較

    たまには(というか初めてか)金融関連ネタを。Bloombergの記事から転載。
    米金融大手ゴールドマン・サックス・グループの1日当たりのトレーディング収入が1億ドル(約89億円)を超えた営業日数は、2009年に131日と過去最多だった。08年度の90日から増え、営業日のほぼ半分で1億ドル超の収入を出したことになる。
    (中略)
    米モルガン・スタンレーの先月の届け出によると、09年に1日のトレーディング収入が1億ドルを超えたのは69営業日だった。
    という記事を見ると、「Goldman Sachs (GS) はMorgan Stanley (MS) よりはるかに凄いなー」と思ってしますが、(この記事の内容からは)そうは言いきれない、という話。

    「1億円の利益をあげるのなんて簡単です。私に1000億円貸してくれれば、それを銀行に預けます。金利が0.1%として、年間1億円儲かります。重要なのはどれだけの資本を使って、どれだけの利益をあげるかということなんです」と言った人がいましたが、このGSとMSの話もそれと同じです。
    1億ドル超の日数が約2倍だとしても、使ったお金が2倍違ったら当然ですよね。

    EDGAR (Electronic Data-Gathering, Analysis, and Retrieval system) (有価証券報告書を閲覧できるシステム)で、GSのannual reportMSのannual reportを見てみました。
    まずは、話題のTrading Net Revenues Distribution(トレーディング収益の分布)のヒストグラムです。GSはこう。
    横軸の単位はmillion dollarです。$100 mil.以上の収益をあげた日が131日あったとわかります。ちなみに、括弧つきの数字はマイナスを意味しますので、$75 mil.以上$100 mil.未満の損失を出した日が2日あったということになります。$100 mil.以上が一括りにされてしまっているので、その先の分布はわかりません。

    MSのヒストグラムはこちら。
    各バーの高さが分からないので正確な値は分かりませんが、$100 mil.以上の日が確かに69日のように見えます。

    さて、この2社がトレーディングに使った資本にはどれくらいの差があるのでしょうか? ここでは資本自体の額ではなくて、どのくらいのリスクを取っていたかをVaR (Value at Risk) という値で比較してみます。

    VaRとは、確率Xでの最大損失を表す数値で、例えば「90%VaRが1億円」とは「10回のうち9回は損失額を1億円以下になるでしょう。でも残りの一回はどれだけ損失が出るかわからないよ」という意味です。

    GSの95%VaRの推移はこうだったそうです。
    縦軸の単位はmillion dollarです。2009年の平均daily VaRは$218 mil.だと書いてあったので、最大約200億円/日の損失を出すかもしれないトレーディングをしていたんですね。ところで、ここまで金額が大きいと感覚が麻痺して、何とも思わなくなりますね。

    MSの95%VaRは、推移が開示されていないので、ヒストグラムを引用します。
    平均$119 mil.だそうです。

    このVaRの比較から、GSはMSの約2倍のリスクを取っていた、約2倍の金額をリスクに晒していた、ということができそうです。
    だとすると、$100 mil.以上の利益を出した日が約2倍多いというのもうなずけます。だって約2倍のお金を使っているわけですから。

    とはいえ、この比較もおかしいですね。そもそも「$100 mil.以上の利益を出した日」って何か特別な意味があるわけじゃなくて、感覚的に「すげー」って思えるから使っているだけで、もっと単純に年間のトレーディングの収益合計で比較すべきです。

    この数値をannual reportから拾ってくると(GSの資料からトレーディング収益のみの値を見つけられなかったので、トレーディングと投資との合計で比較します)・・・。
    • GS: $34,373 mil.
    • MS: $6,393 mil.(ただし、投資で$1,054 mil.の損失をだしているので、トレーディングのみだと$7,447 mil.となります。)

    トレーディング+投資の比較だと約5倍の差があります。2倍のリスクを取って5倍の収益、これは凄いかもしれません。

    というわけでまとめとしては、
    1. 収益の額だけ見てても意味ないよ。
    2. とはいっても、収益/リスクの比で見たらGSの方が大きかった。
    3. でもトレーディングと投資の内訳が分からないから、いまいち釈然としない。
    ということになります。