開発
Up one level鬼の開発マネージャ,仏の。。。
去年まで温厚だった開発マネージャが「今年は,鬼になる」と宣言されたのが,つい先日のことです。anakaさんは厳しい人です。井上さんは恐い人です。大谷さんは頑固な人です。
そういうことで,今年のアリエルには仏がいません。いなくなってしまいました。今年のアリエルはどうなるんでしょうね。新たな戦いの幕開けです。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/9b3c306e958b767a30de30cd30fc30e3-4ecf306e300230023002/tbping
JavaでのVariant型?型不定な値の扱い
アリエルでのディスカッションからの抜粋です。
最初の質問は、
ユーザには多くの属性値があります。 AquaType(aka AirForm, Air-otype)同様、拡張属性を持ちます。 この拡張属性の扱いをJavaでどうすべきでしょうか? 要は、 Map<String, Foo> attributes; で属性名からFoo型の属性値を取れるようにしたいのですが、 Foo型をどうするかです。 Object型にして(アプリ側が)キャストするしかないのでしょうか。 Javaなら、何か素晴しい方法がありますか?
というものです。この質問に対して、C++オタクからの反応は、
C++だとboost::variantというのがあります。
> boost:variant v;
> v.set(1);
> std::cout << v.get<int>() << std::endl;
みたいに使います。setInt()とかsetString()とかいちいち用意する代わりに、
parameterized typeで解決する手法ですが、
Java1.5のGenericで同じことができるかどうかは知りません。
class templateしかサポートしてなくて、function templateは使えなかった
気がするので駄目?それでも、helper class templateを使えばいけるかなぁと
思ったけど、newしないとobjectを作れない不便言語なので、こっちの線も辛いと
ころ。やるとしたら、気持ち悪いけどこんな感じかなぁ。
> Variant v;
> new Setter<int>(v).set(1);
> System.out.println(new Getter<int>(v).get());
C++だとnewが要らないので、いくらかマシな見た目(とパフォーマンス)になります。
[追記]
function templateが使えるっぽい。でも、genericの実装方法から考えると、
> public class Variant {
> public <T> T get() {return (T)value;}
> public <T> Variant set(T value) {this.value = value;}
> private Object value;
> }
みたいなのはコンパイルが通らない気がする。
というものです。C++オタクはさらに調べて、
reflection(Class.cast() method)を使って、
> Variant v;
> v.set(new Interger(1));
> Integer i = v.get("java.lang.Integer");
てのはどうだ。
となっています。ここで、別の人の回答として、
素晴らしい方法は知りません。そもそもJavaには存在しないのか、 それとも私が不勉強なだけなのかもわかりませんせんが。 キャストするか、サポートしている型を答える、その型で値を返す、 などのメソッドを用意した拡張属性の独自のInterfaceとかを作って使うか、 それくらいしか思いつきません。
とここで、ひと段落したかにみめましたが、C++オタクは
> public class Variant {
> private Object value = null;
> public Variant(Object value) {
> this.value = value;
> }
> public get(String typeName)
> throws ClassCastException, ClassNotFoundException {
> return Class.forName(typeName).cast(this.value);
> }
> public set(Object value) {
> this.value = value;
> }
> public set(int value) {
> this.value = new Integer(value);
> }
> // declare for other primitive types.
> }
無意味?
とコードを交えて切り返してきます。ここで、大人の回答が出てきます。
> 無意味? 無意味かどうかは、困ったなあ、と思われたご本人がどう評価されるかだと 思うのですが、そもそも、何に「困った」かですよね。 1. 属性値を利用する側で毎回キャストするのが面倒(あるいは無駄) 2. 型での制約が実質的に無効となってよろしくない という辺りなのかと想像するのですが、もっと深い意味があるのかもしれません (意趣返し)。 2の方の意味が強い場合は、難しいのではないでしょうか
となってきます。この困ったにもともとの質問者ではなくC++オタクが次のように答えています。
例えば、
> static String fooType = "java.lang.Integer";
> void bar(Variant v) {
> Integer foo = v.get(fooType);
> }
とかやって使う。本質的にはtypedefの代わり。
となっています。JavaのVariantの議論に対して、今後の展開はどうなるのでしょう。
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/java306evariant578b-578b4e0d5b9a306a5024306e62713044/tbping
Skype API - 日本人デベロッパーの活躍
アリエルからSkypeに移った 岩田さんのblog で、アリエルの大谷さんが作ったSkype APIの Python Wrapper と、写真共有ソフトの SkyNS について 紹介 しています。大谷さんはlirisさんと名のっているんですね。
岩田さんもSkypeでがんばっているし、頼もしいです。
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/skypedeveloper-janon/tbping
IBMのDB2も無料版をリリース
Oracleに続いて、IBMもデータベースの DB2を無料提供 するようです。データベース製品はオープンソースのPostgreSQLやMySQLが高機能化、高信頼性化する中で、低価格化が進んで、もはや、データベースそれ自体だけでの商売は難しいのかもしれません。かっこいいいい方をすれば、コモディティ化が進んでいると言えます。
データベースそれ自体が低価格化すると、データベースで商売できないんじゃないかというと、そうでもないと思います。ローエンド市場では難しいかもしれませんが、ハイエンド市場では、クラスタ化やバックアップなど、依然として市場は存在しています。
アリエルでも現在のプロジェクトでは、OracleやPostgreSQLをデータベースに採用しようとしていますが、この無料化を受けて、DB2も選択肢に入ってくるかもしれません。でも、IBMだし!
さて、データベースがコモディティ化するにつれて、RDMBSのもつインデックス機能、検索の高速さは魅力です。ファイルシステムにRDBMSを採用するという話は昔から噂になっていましたが、今後どうなっていくんでしょう?つまるところは、WinFSとReiserFSですが。
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/ibm306edb23082712165997248309230ea30ea30fc30b9/tbping
Javaでの空文字の判定方法
アリエル社内の掲示板でJavaでの空文字の判定方法が密かなブームを読んでいます。例によって、かなり脱線した議論もあります。
そもそもの質問者は、
Javaでの空かどうかの判定は、どちらがいいのでしょう?
- str.equals("")
- str.length() == 0
最初の方法はタイプが楽ですが、効率が悪そうです。二つ目の方法は速そうですが、空文字の判定かどうかがわかりづらいです。
というものです。ここで、Pythonistaが
Python的には、s is None
と発言してしまったことに議論の発散が始まります。確かにPythonの方がJavaに比べてシンプルで直感的です。C/C++に慣れているおじさん世代には反論を呼びそうです。
質問者は、Pythonistaに反論して、
C的には、
- *str == '\0'
- strlen(str) == 0
二つ目の方法はとても遅くなる可能性があるので、邪悪です。
C++的には、basic_stringを使って、str.empty()が安全確実。
と言うものでした。JavaとCでは、null判定が前提として行われるものとしています。 他の言語を見てきたあとに、Javaの話にようやく戻ります。
第3の方法として、
try { str[0]; }
catch (Exception e) { /* 空文字! */ }
がPythonistaによって提案されました。配列で存在しない要素にアクセスするので、Javaの例外が発生することを利用した実装です。例外で処理するので、当然実効速度は遅くなります。
ここまで来たら、もうやけくそです。さらに邪悪さをまして、次のような案が提案されています。
文字列のhash値を比較する方法
str.hashCode() == "".hashCode()
StringクラスのindexOfを使ってみる
for (int i = 0; i < 65536; i++) {
if (str.indexOf(i) >= 0 ) {
// 空文字ではない
return;
}
}
この二つの方法に対するコメントは、「まだまだ、邪悪さが足りません。」と言うことでした。さて、あなたならどう書く?
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/empty-string/tbping
文字列リテラルもオブジェクト
犯人は誰だ
アリエルの新プロジェクトでは、Eclipseを使っています。バックエンドのソースコード管理にはSubversionを使っています。Subversion上には、Eclipseの設定ファイルなどもコミットされているので、最新のリビジョンを取得すれば、Eclipseの設定も変更されます。
今日の最新リビジョンを取得すると、須崎さんが苦労して設定した内容が消されています。そのことに気付いたanakaさんは、犯人探しを始めました。まず、疑いが向けられたのは、温厚でおとなしい福島さんです。無実の福島さんは必死に抵抗しましたが、anakaさんは聞き入れてくれません。
次に疑いの目が向けられたのはEclipseとSubversionです。ソフトウェアのバグでリビジョンが戻ってしまったということです。大谷さんがログを調査すると、須崎さんがコミットした後にanakaさんのコミットしたファイルがあります。そのlogには、「correct build error」と書かれています。次にdiffを調べると、anakaさんが消えたといっている設定が、anakaさんのコミットで行われていることが判明しました。
でも、いまだにanakaさんはSubversionのバグだと主張しています。かわいそうなのは無実の福島さんです。
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/72af4eba306f8ab0/tbping
「for 文 2.0」からのメタメッセージ
「 for 文 2.0(笑) 」を受けて、アリエル社内ではまた変な議論が繰り返されました。 事の発端は須崎さんがこの記事を紹介したところから始まります。JavaScriptの記事なのに、いきなり、まったく別の言語に話が及ぶのがアリエルらしいところです。
まずは、JavaScriptの
for(var i = 0, len = array.length; i < len; i++) {
....
}
を受けて、井上さんが
Javaでもこの恰好悪いテクニックが有効だったりする事実が悲しい... (JITがあるから関係無いとIBMは言いますが)。
という発言です。彼は今、Javaのコードを書いているので、当然の発言でしょう。これに対して、生粋のJavaプログラマは
私は、1行の中に複数の操作(!?)を書かないようにしています。 でもそれは決してJVMの知性に対する不信のせいではなく、自分のコード読解能力が低 いためです... 自分の能力が環境よりも低いために文句も言わずに従順でいられる、ってのは幸せなのでしょうか、不幸せなのでしょうか。
少し謙遜が入っていますが、1行の中に複数の操作があると可読性が悪くなるという主張です。これに対して、井上さんは、
ちなみに、1行に複数書くことがポイントではなく、ローカル変数(上の例で言えばlenをわざわざ使う)を使う部分がポイントです。「Javaの鉄則」でも、Javaの高速化のための技術として紹介されていました。
不明なのが、この技術(参照が多い変数はいったんローカル変数に代入すべき)は、Javaがどれだけ進化しても変わらない鉄則なのか?、です。上の例で、array.lengthの部分がgetter系のメソッドの場合、Javaはループの終了チェックでいつも関数呼び出しをするのか、それとも(なんらかの魔法で)最適化が起きるのか、ここが分かりません。
さて、これで、最適化の話に変わっていきます。もう一人のJavaフリークは、
昔の記憶では、
int[] hoge; hoge.lengthはあまり遅くならない。
SomeObj hoge; hoge.length()見たいなのは、関数呼び出しのコストがかかり、最適化しにくいので遅くなる。
とのことです。昔の記憶というところに反応して井上さんはIBMの魔法により、すべてが都市伝説になるかもしれないということを紹介しています。
昔の記憶で何かを書くと、IBMが文句を言うかもしれません。
- http://www-06.ibm.com/jp/developerworks/java/030627/j_j-jtp04223.html
- http://www-06.ibm.com/jp/developerworks/java/051104/j_j-jtp09275.shtml
しかし、IBMの言うことは嘘っぽい(局所的には嘘ではなくても、それを積み上げた結果、Javaが速くなっているのかに疑問があります)。
Java Performance Tuning News (http://javanews.jp/javap/)でも、都合が良いデータには「当然でしょう」とクールに反応し、都合が悪いデータには「そんな(局所的な)パフォーマンスが重要でしょうか?」と受け流すのが常です。
ここで、皆さんお待ちかねのC++オタクの登場です。
malloc()と比較すれば、大抵のアロケーション実装は速いです。でも、それじゃC++と比較したことにはなりません。new演算子がmalloc()を直接使うような実装はまずないし、operator newをオーバーロードしてクラス毎に最適なアロケーションを提供するという手段もあります。
という前提を無視して「Javaの方が速いんだぜ、ふふん」とか言われてもなぁ。エスケープ分析は、本当に機能するならすごいけど(賢いJVMであれば、ってあたりが怪しい)。
以下、昔話。
.NETのCLRが上のページで言うところのコピー型コレクターを実装していて、JavaのGCよりもあらゆる面で高速だと主張する記事が、MSJだかMSDN MAGAZINEだかに載っていました。5年くらい前の話です。
と、.NETは5年も前からすごそうです。結局、何がいいのか結論が出ないまま、次のようにまとまりました。
- 大谷さんとアリエルのJavaプログラマたちは暖かい視線でJavaを見守っている
- 中山さん(C++オタク)はJavaを心底馬鹿にしている
- 井上さんはIBMをさらに馬鹿にしている
お後がよろしいようで。
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/300cfor-6587-2-0300d304b3089306e30e130bf30e130c330bb30fc/tbping
[Java] 「.」のコストとfor文の最適化
Javaでタプルを返したい
Java初心者の開発者です。
PythonやPerlのようにJavaのメソッド返したいのですが、どうすればいいのでしょう?Pythonだと
def func():
return 1, "func"
のようにかけます。Cの場合だと、
void func(int* i, char** s) {
*i = 1
*s = "hoge";
}
のようになります。Javaではどう書くのが正しいのでしょう。僕が思いついた方法を書きます。
方法1(配列を使う):
class C {
void func(int[] i, String[] s) {
i[0] = 1;
s[0] = "hoge";
}
}
方法2(オブジェクトを返す):
class C {
public class D {
public int i;
public String s;
}
D func() {
D d = new D();
d.i = 1;
d.s = "hoge";
return d;
}
}
最初の方法だとC的で古い世代の人だとばれてしまいます。二つ目の方法だと、単にデータを返したいためだけにクラスを定義するので、違和感があります。
Java的にはどうすればよいのでしょうか?
- Category(s)
- 開発
- The URL to Trackback this entry is:
- http://dev.ariel-networks.com/Members/dev/java30bf30eb30928fd43057305f3044/tbping
Re:Javaでタプルを返したい
Object[] func() {
return new Object[]{new Interger(1), "hoge"};
}
JDK1.5なら
Object[] func() {
return new Object[]{1, "hoge"};
}
Genericを使って、
public class Tuple
public L left;
public R right;
Tuple(L left, R right) {
this.left = left;
this.right = right;
}
}
Tuple
return new Tuple
}
3値のTupleを返す場合は、
Tuple
return new Tuple
}
動くかどうかは知りません。
Re:Javaでタプルを返したい
困ったもんだ。
public class Tuple<L, R> {
public L left;
public R right;
Tuple(L left, R right) {
this.left = left;
this.right = right;
}
}
Tuple<Integer, String> func() {
return new Tuple<Integer, String>(1, "hoge");
}
Tuple<Integer, Tuple<String, Double>> func3() {
return new Tuple<Integer, Tuple<String, Double>>(1, new Tuple<String, Double>("hoge", 3.14);
}
hashを比較する方法は遅い上に、確実性がないという問題を抱えています。
邪悪なのとは違って、単にバグってます。