Borland,約7500万ドルでMicro Focusに身売り
Borland,約7500万ドルでMicro Focusに身売り(ITpro)
米Borland、7,500万ドルでMicro Forcusに売却へ(マイコミジャーナル)
OracleによるSunの買収をスルーしてしまった身であれですが、
いよいよBorlandという名前が無くなるかと思うと、寂しさを感じてしまいました。
学生時代は「C++ Builder」を使っていましたし、
入社当時、JBuilderの「OpenTools」というAPIを使って、
いろいろツールを開発したりしてたのも、懐かしい思い出です。
(Eclipseを使い始めたのも自分なので、
社内的にはJBuilderに引導を渡す格好になってしまいましたが...)
とはいえ、開発ツールベンダとしては、
CodeGearに分社化&売却されてましたから、
既に遠い存在だったわけです。
最近は、StarTeamとかSilkPerformerとかで、
お客様が使っているところを、
お目にする事が多かったですね。
IT業界の再編に拍車がかかってますが、
日本国内のユーザサポートを簡単に切り捨てないよう、
お願いしたいところです。
80:20の法則(part 1)
ENdoSnipeの設定が簡単になりましたで取り上げているように、
ENdoSnipeのVer. 4.0からは、メソッドの実装内容を見て、
BCIの対象とするかどうかを判断します。
getterやsetter、あるいは単純に他のメソッドを呼び出すだけのようなものは、
そもそも性能問題が発生する事がないので、計測不要と考えたというわけです。
実際には、単純なメソッドを何度も呼び出す事で、
性能問題が発生する事はあり得ますが、
この場合は呼び出し元のメソッドの処理時間の増大として検出されるでしょう。
この機能をつけた理由は先に挙げたブログを読んで頂くとして、
実際にどれぐらい効果的かを検証しました。
以前は以下のように設定していました。
############################################################
# Settings for S2JSF Example
############################################################
examples.jsf.action.impl..*Impl,JavelinConverter
examples.jsf.logic.impl..*Impl,JavelinConverter
examples.jsf.dao..*,JavelinConverter
Action、Logic、Daoの各層の主要なメソッドを対象にしていますね。
簡単なサンプルプログラム程度であれば、
試行錯誤してこのような設定を決めれば良いのですが、
急場の大規模プロジェクトではそのような時間もないので、
改善が必要だったわけです。
では、新機能を用いた新しい設定は以下の通りです。
############################################################
# Settings for S2JSF Example
############################################################
examples.jsf..*,JavelinConverter
examples.jsfパッケージ配下に含まれる全クラスの、
全メソッドを性能測定の対象に指定しています。
では、これで動作比較をやってみようと思います。
観点としては、
- 対象クラス・メソッド数の変化
- クラス図・シーケンス図の変化
- オーバヘッドの変化
を取り上げたいと思います。
それでは、続きをお楽しみに。
パッケージ開発につきものの悩み
ENdoSnipeはVer. 4.0のリリースを5月末に控えているのですが、
最近の悩みは素敵な追加機能を際限なく、思いついてしまう事です。
今回、思いついてしまったのはこれら。
1は前々回、前回と書いてきた、
カラム名指定でResultSetから値を取得している処理を検出する機能です。
特定のJDBCドライバをお使いの人であれば、役に立つと思います。
2はArrayListやVectorの線形検索を検出する機能です。ソースコードレビューなんかしなくても、
機能を動作させるだけで、PerformanceDoctorが、
「線形検索を実行しています。」と言ってくれるので、
この機能も非常に便利なはず。
で、3。
ENdoSnipeを適用した状態で、
システムのどれくらいの機能を実行したかの目安になります。
メソッドレベルでの実行有無までしか見ないので、
条件分岐などはカバーできず、あくまで「擬似」レベルではありますが。
これは品質保証部などをやっている人には堪らないんじゃないかと。
かく言う私も、システム診断を請け負った時に、
診断の網羅率を報告できるので、これは欲しい。
なんて事を、
リリース2ヶ月前に思いついてしまうのだから、
自分でも嫌になります。
でも、思いついたら作らずにはいられない!
もとい、作ってもらわずにはいられない!
・・・作るのは私じゃなくてメンバなのです。
なので、メンバには非常に申し訳ないですが、
Ver. 4.0で実現することになりました。
ユーザの皆さんは、実現された機能を見て、
メンバの頑張りにも思いを巡らせて頂けると幸いです。
(続)JDBCに関するふとした疑問
ちょっと時間が空きましたが、前回の日記で書いた疑問の検証をやってみました。
前回残った疑問は、
- カラム数が多いと変換処理のオーバヘッドが無視できなくなるのでは無いか?
- 変換処理が配列の走査で実現されているドライバが無いか?
でしたので、まず、
「変換処理がHashMapによる検索で実現されているドライバ(eg. PostgreSQL)」と
「変換処理がListの走査で実現されているドライバ」の、
処理速度の比較をやってみました。
本当にDBMSから検索した結果で調べるのが正しいのですが、
時間がないのでまずはそれらしいプログラムを作ってシミュレーションです。
とりあえず、10000レコードを処理するとして、
カラム数を、100 → 200 → 400 → 800
と変化させた時の所要時間を測定してみました。
(CPUはCore2 Duo T8100/2.1 GHz、です。)
カラム数 | HashMap | List |
---|---|---|
100 | 112 | 2588 |
200 | 61 | 8481 |
400 | 117 | 28979 |
800 | 218 | 131359 |
(単位:ミリ秒)
…という事で、カラム数が400まで達すると30秒、
800に達すると130秒のオーバヘッドが生じる計算になります。
まあ、それほどでも無いですね。
これを多いと見るか、少ないと見るか・・・、
基本的には影響無いレベルですが、
SQLによっては、響くケースもあるかも知れませんね。
バッチ処理だとレコード数がこの10倍、100倍という事もあるので、
オーバヘッドも無視できない値になるかも知れません。
(400カラムのテーブルを10万件処理すると、
5分のオーバヘッドが生じるというのは、
結構、大きいかも・・・)
…ところで、こんな事が疑問になったのも、
ENdoSnipeでDBアクセスの処理時間を計っていたら、
思いのほか、CPU使用時間が長い場合があったからです。
お使いのJDBCによっては、
オーバヘッドが無視できないものも、
あるかも知れませんね。
というわけで、
- カラム数が多いと変換処理のオーバヘッドが無視できなくなるのでは無いか?
の検証はできました。
残る、
- 変換処理が配列の走査で実現されているドライバが無いか?
もやってみたいところですが、公表が難しそうですね。
…というわけで、実施は見送ると思いますが、
気になる方は、調べてみて下さい。
JDBCに関するふとした疑問
JDBCについてちょっとした疑問がわきました。
大抵の方がご存じの通り、JDBCでResultSetから値を取得する場合、
- インデクス指定
- カラム名指定
の2通りの方法があります。
例えばこんな感じですね。
インデクス指定
ResultSet#getInt(int columnIndex)
カラム名指定
ResultSet#getInt(String columnName)
保守性からいえばカラム名指定の方が分かりやすいのは明白ですが、
カラム名 → インデクスの変換処理が必要になるのは確実です。
実際にPostgreSQLのJDBCドライバ(jdbc-8.3-604)では、
public int getInt(String columnName) throws SQLException
{
return getInt(findColumn(columnName));
}
と、カラム名指定の場合はインデクスへの変換処理をしていますね。
で、処理速度的にこの変換処理が無視できなくなるのか、気になったわけです。
変換処理を見てみましょう。
private int findColumnIndex(String columnName)
{
if (columnNameIndexMap == null)
{
columnNameIndexMap = new HashMap(fields.length * 2);
// The JDBC spec says when you have duplicate columns names,
// the first one should be returned. So load the map in
// reverse order so the first ones will overwrite later ones.
for (int i = fields.length - 1; i >= 0; i--)
{
columnNameIndexMap.put(fields[i].getColumnLabel().toLowerCase(Locale.US), new Integer(i + 1));
}
}Integer index = (Integer)columnNameIndexMap.get(columnName);
if (index != null)
{
return index.intValue();
}index = (Integer)columnNameIndexMap.get(columnName.toLowerCase(Locale.US));
if (index != null)
{
columnNameIndexMap.put(columnName, index);
return index.intValue();
}return 0;
}
予想通り、変換にはHashMapが使われています。
ほとんど、通常の処理では気にならないはずですね。
ただし、カラム数が多いとオーバヘッドが気になってくるかも知れません。
もう1点、気になるのは、ソースコード中に、
// The JDBC spec says when you have duplicate columns names,
// the first one should be returned. So load the map in
// reverse order so the first ones will overwrite later ones.
とのコメントがあるという事でしょうか。
「JDBCの仕様に従うために、逆順に配列を走査してますよ」と。
面白い工夫ですね。
そうすると、仕様を素直に守るために、
配列を先頭から舐めるJDBCドライバ(当然遅い)
の実装もありそうですね。
ここまでの調査からは、
- カラム数が多いと変換処理のオーバヘッドが無視できなくなるのでは無いか?
- 変換処理が配列の走査で実現されているドライバが無いか?
という感じです。
おいおい、検証してみようと思います。
ま、あまり気にするレベルでは無いのかも知れませんが。