[ADP開発日誌]Ver0.5アルファ版 リリース

ADPの開発版(Ver0.5)をリリースしました。

SourceForge.JPにてリリースしております。GPLで公開します。
以下のページからソースおよびプロジェクトファイルがダウンロードできます。
http://sourceforge.jp/projects/adp/

以前、[ADP開発日誌]ソースコードを公開するか?でソースは公開しないと言っていましたが、結局ソースで公開します。Windows版の方はバイナリ版も公開しています。

理由ですが、知人にMacOSXでコンパイルして頂いたのですが、コンパイル自体は通ったということで案外移植性が高いソースのようで、『ならばソース公開していろんな人に使ってもらった方がよいな』ということで公開しました。

実際に触りだすとあれやこれや色々いじりたくなり、そういう意味ではソース公開してちょこちょこリリースした方が活動状況も解ってよいかなというのもあります。まぁ何はともあれ後はドキュメントとサンプル(とテストプログラム)に集中したいのですが、またソース修正したりするかもしれません・・・。

P.S. Mさんへ、GitHubではなくてSourceForge.JPで公開でしました。GitHubも考えたのですが、諸事情によりSourceForge.JPの方が使いやすかったのでとりあえずこちらで公開しましたです。せっかく教えて頂いたのですがすみませんです。

[ADP開発日誌]経済ゲームを作ってみよう

最近ADP関連のブログの更新がありませんでしたが、久しぶりのADPの布教活動を。

今年も飛び交う「日本みたいになるぞ」報道に書かれていますが、日本の失われた10年は海外でも悪い見本と取られていますが、もっと驚くことに、引用しますと、

デフレというおなじみのお化けがアメリカ経済の懸念材料として再登場している。(中略)日本のデフレを10年以上も研究した結果、エコノミストたちは次第に、自分たちはデフレの仕組みを何も分かっていないと気づき始めている

にありますとおり、デフレの仕組が解っていない事実に、なるほどと思うとともに『エコノミストは何をやっとんのじゃ!』というある種の憤りを感じたりする。特にソフトウェアエンジニアはコンピュータが動かないとお客からのある種のプレッシャーを感じるのだが、『エコノミストは、この日本の状況下である種の責任感とか使命感とかには駆られないのだろうか?』とか色々考える。

もっとも多くの人も何かおかしいということに気づいているかとは思うのですが、『ではどうやって解決するの?』と思われるでしょう。そ・こ・で、ADPの登場です!(ってかなり強引な宣伝です)。つまり、あ~だ、こ~だと議論ばかりに頼らずにもっと科学的にシミューレーションのような手法を使ってデフレのメカニズムの解明とかの研究をしませんか?という提案です。

ADPですが、Another Data Processorの名前のとおり、経済シミュレーションのようにややこしいシステム(真面目な言葉を使えば複雑系)を容易に記述できるようにというコンセプトで開発を行っています。
サンプルでちょっとした経済ゲームを作成してみました。
ソースも添付しましたので参照して頂ければ解るかと思いますが、様々な条件や計算を行うシステムでも比較的スッキリと記述できるかと思います。

ちなみに、ゲーム自体は興味本位で作成したのですが、作成したモデルですが、製品を無限に作成できる場合、人口は安定的に増える。ので上限を設けたら、今のところ安定的に人口増加するパラメータが見つかっていません。見つけた人は連絡を!

新規で作り直すか? 改修するか?

チョット野暮用が入りADPの開発(というかブログの更新が)滞ってます。自慢にもなっていない記事をそのままにしておくのも何なので、ちょっとしたネタをアップします。

他人が作ったソフトウェアにバグがあったり仕様変更で改修したりする場合、新規で作り直すか、改修するかが議論になったりすることがあります。

良く聞く意見に
 『バグバグでソースも汚いので新規で作り直しましょう』
というのがありますが、この『ソースが汚い』という意見ですが、往々にして主観が入っていることがあります。つまり、
その人のコーディングスタイルに合っていない→ソースが汚い
ということを言っている場合があり、この意見を鵜呑みにして新規開発の道に行くのは危険だったりします。
良くあるミスが、既存のコードに入っていたノウハウ(エラー処理や例外的な処理など)が新規開発で消えてしまい、却ってバグバグになったり、実際にはそう見栄えも良くなっておらず結局、工数だけかけたということになったりします。

新規なのか改修なのかというのはケースバイケースの面があり、あまり一般論では語りにくいのですが、私の場合、以下のルールで新規開発を行います。

  1. 既存のコードがある場合、基本は改修で行います。
    バグがあるからとかソースが汚いという理由で新規開発を行いたくなりますが、その程度では新規開発はしません。
  2. 改修に工数が掛る場合、仕様を完全に把握できかつコーディングテクニック上ではなくパラダイムだったりアルゴリズムが元のコードよりも有効なものが使える場合、先ずは関数レベルから置き換える。
    オブジェクト指向を使っていないコードにオブジェクト指向を行ってみるとか、サーチアルゴリズムを別のものに入れ替えるとか、if文の条件が複雑だか良く見ると簡単にできる場合に簡単にするとか、コピーペーストしているコードで共通部分を関数にするとかです。
  3. 出来ることならテストプログラムを書き、デグレードを防ぐ。
  4. 徐々に改修するコードを広げてゆく。

とまぁこんな感じでやってます。

ちなみに、自分が過去に作ったコードは結構大胆に書き換えたりします。自分が作成したものの場合、1回目より2回目の方がソースが綺麗に書けるということと、『仕様を完全に把握している』という条件をクリアしやすい為です。

英検(2) -苦手意識-

 ちょっと前の話ですが、7/11は選挙があったのですが、私にとっては英検の2次試験(面接)がありました。
その日は準備不足もたたって朝からブルーになっていた。準2級を受けた時は簡単だったので気楽に受験できたのだが、2級の問題ではもう少ししゃべらないとダメなようで『イヤ・・・俺にはむり・・・』という感じで、受験する前から敗北感でいっぱいだった。
昼過ぎに会場に入り空調の効かない講堂で結構待たされ悶々としている中で余計なことを考え出した。
ここ10年ぐらい、散発的ではあるが英語の勉強をしてきて、楽しいと思ったこともなくせいぜい周りに、程度の低い自慢をする程度だったのだが、英検2級に合格したい思いとムリという思いが交錯してなんとも言えない緊張感を持ちながら『テストは何時や~』と待っていた。
しまいには気持ち悪くなり(多分、暑さのせいなのだが・・・)、心を落ち着かせようと『平常心、平常心。普通に会話したらええから・・・』と自分に言い聞かせ。面接に挑んだ。
面接官は、欧米人男性の方でどうも朝からのテストで相当疲れているらしく、「あ、はい、じゃこれ読んで」ってなノリで流して来た。
こちらも拍子抜けした感があり、力が抜けて英会話の授業のノリで受験してしまい、テスト中に思わず、「○○の意味ってなんですか?」みたいなことを聞いてしまった。
その時に面接官が顔が曇り、『この男は何を聞いとんのじゃ!』みたいな顔をした。

もちろんテストなので単語の意味を聞くのはご法度で、十数年ぶりの自己嫌悪で悶々とした日々が続いたが、今日の速報を見ると無事に合格していた。あぁ~本当によかった。

IT系の資格試験の場合は合格でも不合格でもなんとも思わないのだが(なぜなら実際に仕事をしていく上で資格が役にたったことは一度もないので)、英検の場合は本当にうれしかったです。次回もストレスに負けないようにテストに臨もう。

眼精疲労なのでブログを読みやすくした

2か月程前になりますが、どうも目の調子が悪く眼鏡を変えました。少し度を弱くしたのですが、調子が戻り一安心していたのですが、最近、また調子が悪くなったようで、一部見えなくなった(しばらくすると見えるようになる)ので、慌てて眼科に行きました。
検査では異常が見当たらずお医者さん曰く『眼精疲労』ではないかということで目薬をもらいました。
確かに眼精疲労のようで、目薬をさすと一発で治りました。ただ、根本的にどうも目が疲れているようで、大事にしないといけないようです。

という訳でもないですが、ブログのページを変えました。コードを読みやすくしました。
今から思うと前のデザインは、やっつけ感いっぱいでした・・・。

freshmeat

ADPの布教活動の一環ですが、freshmeatというソフトウェアの告知サイトがあったので登録しました。
ADP | freshmeat.net

freshmeat自体は、オープンソースへの参加は難しくない(5)作ってみる 前編 で知りました。freshmeatのサイトは英語が使われているのですが、なかなか親切なサイトで、以下のように私のつたない英語を修正してもらえました。

『ADP (Another Data Processor) is a programing language is designed for Web database programing. It is a scripting language and a lightweight programming language in which it is possible to mix SQL easily. It is easy to install.』

ちなみに元の英文は・・・まぁやめましょう。

C++/STL 1GBのintのソートにかかる時間 2010

未踏の説明会の続きですが、説明会の中に技術的なセッションもありまして、グーグル株式会社のソフトウェアエンジニア 鵜飼さんの講演が面白かったのですが、その中で、『1GBのintのソートにかかる時間は、封筒の裏計算で、30秒』というのがありました。

パフォーマンスには一家言ある私ですが、さすがに1GBのintのソート時間にはピンと来ませんでした。
という訳で、ホントかどうかやってみました。


#include <vector>
#include <algorithm>
#include <iostream>
#include <time.h>

using namespace std;

int main(void)
{
    vector        values;

    srand(time(0));
    // vectorに適当な値を入れる
    for ( int i = 0; i < 1024*1024*1024 / sizeof(int); i++ ) {
        values.push_back((int)(rand()*rand()-i));
    }

    // ソートする
    clock_t        t = clock();
    sort( values.begin(), values.end());
    cout << "Time(sort) is "
         << (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;

    return 0;
}

実行時間(Core i7-920 Windows7 コンパイルVC++2008 リリースモード 64ビットモード)は以下になります。上記のプログラムですが、32ビットモードでは動作しません。32ビットプロセスはリニアに1GBのメモリは確保できないです。

Time(sort) is 43.895sec.

なるほど、確かに30秒からそう離れていません。
ちなみに、この手の封筒の裏計算ですが、桁が違わなければOKと考えてよいでしょう。なので、細かい値の違いが問題になる場合は、実アプリでキチンとベンチマークをとるのがよいでしょう。
この手の結果の受け止め方ですが、おそらく一般の業務アプリを作成する人にとっては『理論的限界値』程度に思っていた方がよいでしょう。つまり

 1秒間に数百万個のint型のソートができる。数千万個になったら要注意。

と思っておけばよろしいかと思います。実際に私の経験でも行数が数百万件のソートをSQLで行うのはあまり問題になることはなかったです。(もちろんメモリが十分にあればの話ですが)。

実行時間の詳細ですが、説明では以下のとおりでした。
 ・要素を比較する回数(ソートのオーダnlogn)から、
  2^28 * log(2^28) → 2^28 * 28 → 2^28 * 2^5 → 2^33(2の33乗)回
 ・比較に際してのL1キャッシュのアクセス時間 0.5ns / 回
 ・比較に際してのブランチペナルティ 2.5ns / 回(2回に1回ペナルティがあると仮定する)

 実行時間 2^33 * (0.5 + 2.5)nsec = 25.76sec 約30秒

ただ、上記の計算ですが、ブランチペナルティが全体の速度を決定しているというのはいささか疑問があります。上記の場合、メモリのアクセス回数から計算した方が良いのでは?と思います。
つまり、
 ・要素を比較する回数(ソートのオーダnlogn)から、
  2^28 * log(2^28) → 2^28 * 28 → 2^28 * 2^5 → 2^33(2の33乗)回
 ・ 比較に際してのメモリアクセス回数 2回(リード&ライト) 2*4バイト
 ・キャッシュライン 32バイト

 ・メインメモリへのアクセス回数 2^33 * 2 * 4 / 32 = 2^31 回
 ・メインメモリアクセス性能 1回のアクセス 10nsec(DDR3のレイテンシーから)

 実行時間 2^31 * 10nsec = 21.47sec

うーん、数値的には似たり寄ったりであまり変わらないか・・・・

未踏ソフトの説明会に行ってきました

ADPを開発する上で避けて通れないのが、『どうやって流行らすか?』になります。
もっとも、自己満足と言われようが何と言われようがADPの開発は続けますし使ってもいくと思うので、流行らなくてもという良いという考えもなくもないのです。
しかし、個人でやる開発ならそれでOKなのですが、人と仕事をする上ではこの手のこだわりが障害になったりしますし、この手の複雑なソフトウェアは広く動作させてフィードバックをもらうことが品質面からも重要になります。

要するにプロのエンジニア目線で考えると、自分が作った言語とは言えマイナーなプログラミング言語にかかわっているヒマはないということになるのですが、であればメジャーにすればよいということで『流行らそう』ということになりました。
もちろん、大前提として、流行らすに値する言語かということもありますが、そのあたりについてはまたの機会に書きます。

で、具体的に何をするねんって話になるのですが、色々考えているのですが、もちろんこのブログも布教活動の一環としてやっているのですが、その1つとして、未踏ソフトに挑戦するということがあります。ちなみにその後は、LLイベント(http://ll.jus.or.jp/)にパネリストとしてADPを布教することを目標にしております。

未踏ソフトですが、以前は2008年の下期に応募したのですが、残念ながら採択にならず、その後仕事が忙しくなったので応募していなかったのですが、今年はタイミングよく応募できそうです。
そのような訳でちょっと知らなかったのが、いつからか年齢制限(というか年齢での優遇)が35歳未満になったらしく、今年40の私としては、『いまさら応募するのもな~』という思いと、制度の趣旨が『人材発掘』つまり天才を発掘しようということらしく『じゃなんで俺を選ばないの?』という訳のわからん自信とが交錯し、どうするか迷う面があるのですが、とにもかくにも人から評価を受けるというのは非常に大事なことなのではあります。で決めかねています。

説明会の内容ですが、私的には面白い内容でした。単なる制度の説明だけでなくちょっと聞けない技術的な話もありましたので、たまにはこういうイベントに参加するのも良いものだと思います。これからもやるでしょうから未踏に応募する人は一度説明会に参加されることをお勧めします。

C++ オブジェクトを new/delete するコスト

少し間があきましたが、技術ネタで。
new/deleteは、C++はもとより、最近のプログラミング言語なら当たり前のようにやる(おっとdeleteはしないか)かと思いますが、そのコストについてはついつい忘れがちになります。

ADPは、C++で作成しているのですが、オブジェクトをリサイクルするように変更したところ、実行速度が倍ぐらいに速くなった。もともとは速くするために行った訳ではないのだが意外な副産物となった。

Visutal C++ではいつのころからか(遅くともVC++ 2003以降)、newすると最終的にはWindowsのAPIが呼び出される。パフォーマンスにシビアなシステムでは、ローカル変数の定義のようにお気楽に出来るものではないかもしれない。

といっても理屈だけではなんなので、具体的にどのくらいのコストがかかるかベンチマークしてみました。


#include <iostream>
#include <vector>
#include <time.h>

using namespace std;

class myobject {
    int    myvalue;
public:
    myobject() : myvalue(0){};
};

myobject    *myobjects[10*1000*1000];

int test(int v)
{
    return v * 1000;
}


int main(void)
{
    clock_t        t = clock();

    // new(1千万回)
    t = clock();
    for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
        myobjects[i] = new myobject();
    }
    cout << "Time(new) is "
         << (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;

    // delete(1千万回)
    t = clock();
    for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
        delete myobjects[i];
    }
    cout << "Time(delete) is "
         << (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;

    // 関数呼出し(1千万回)
    t = clock();
    for ( int i = 0; i < 10 * 1000 * 1000; i++ ) {
        test(i);
    }
    cout << "Time(function call) is "
         << (double)(clock() - t) / CLOCKS_PER_SEC << "sec." << endl;

    return 0;
}

以下、実行結果(Core i7-920 Windows7 コンパイルVC++2008 デバッグモード)

Time(new) is 2.065sec.
Time(delete) is 2.35sec.
Time(function call) is 0.26sec.

Windows環境でC++だと、おおむね1秒間に約数百万個のオブジェクトが作れるようです。また、関数呼び出しは数千万回できるようです。
上記の実行結果はデバッグ環境で行っていますので、リリースモードで実行するとこれから数倍速くなります。
この手の数字にピンとこない人の為に補足しますと、最近のコンピュータは1秒間に数十億個の命令が実行できます。単純に計算しますと、メモリの確保は約千個の命令を使っており、関数呼び出しは約百個の命令を使うということになります。

とある顧客とのやりとり

先週は、嫌なお客の話をしたので、今週は、もう一度ご一緒に仕事をしてみたいお客様の話をします。
そのお客さんは、とあるECサイトを業者に作ってもらったのですが、残念ながらバグバグのシステムで大変不満を持たれていました。おりしも不況と重なって会社もリストラを始めたり、元々の担当者が止めたりで、新しく担当になった方は、業務は解るが、IT(WEBサイト)のことはよく知らないといった感じの人でした。色々不満もあったかと思いますが、そういったことは表に出さないで真面目にプロジェクトに取り組まれていました。
もっともITのことはあまり詳しくなかったので私が業者との交渉(バグの伝え方から、改修予算の値引き交渉やら、相手から来たメールの意図を翻訳したり)のサポートを行っていたました。

ただ、ECサイトによくあることですが、いかんせん売上が上がりませんでした。そういう中で次期開発の話が出てきたのですが、当然やりたいことにお金(予算、売り上げ)がついてこないので、そのギャップに担当者の方が悩んでいまして、ミーティングで愚痴を言われていました。そこで、思わず私が、
「今までの経験上、上手く行かないやり方を続けていてはダメになるばかりでっせ」
と言いました。

つまり、売上を上げていないのなら、無理に開発を進めるのではなく現行のシステムは修正にとどめたり、儲からないサービスやめたりするのも手ですよというある意味当然のことを言ったのですが、ただ、多くの日本人は『止める』という発想がなかなかできないようで、私も過去にこのようなことを言ってプロジェクトから外されたこともありました(本音を言ってくれてありがとうという人もいました)。

今回もこれは言い過ぎかなとも思ったのですが、この一言が担当者を救ったらしく、サービスメニューの構成を変えるように話しが進みました。以前なら『生意気なことを言うな』と言われるところだったのですが、平成不況も長くなると営業の現場の人もプライドを捨てて話をされるようになったようです。

その後、残念なことにやはり改修の規模が大きくなり、コストがかさむと同時にリストラが進み担当者もご勇退されプロジェクト自体が空中分解して、結局はそのECサイトはまったく改善をされずに閉鎖になりました。

私自身は営業的に失敗したプロジェクトをいくつも経験しているし僭越ながら自社のシステムを含めて成功しているプロジェクトも経験しているのですが、そのプロジェクトが終了したことは残念でした。もちろん予算がないプロジェクトだったので私自身もアドバイザーという形で週に1回しか打ち合わせに参加していなかったので、私のかかわり方として不完全燃焼な面もありました。
次回、その顧客と仕事をする機会があればぜひもっと良い結果を出せるように頑張りたいと思いました。

不況が長く続きますが、こういう難局を乗り越えるのもソフトウェアエンジニアというよりビジネスパーソンとして真価を問われていることだと思います。頑張りたいものです。