2010年12月18日土曜日

Googleも採用するJavaが、Appleが勧めるObjective Cより開発効率が高い7つの理由

このエントリーをはてなブックマークに追加
Pocket

以前のエントリーでObjective Cの実行速度を評価したところ、Javaの方が開発効率が高いとの指摘を多数頂いた。

これ自体に異議は無いのだが、両者は利用用途が異なる場合が多く、プログラマーにも質的な差があるので『開発効率』を定量的に評価するのは難しく、両方での開発経験がある人間以外は差異を把握しづらい。

そこでデスクトップ/スマートフォン・アプリケーションの作成を念頭におき、Objective CとJavaの定性的な比較を行い、JavaがObjective Cより開発効率が高い理由を以下の7点に整理した。なお、開発効率性を議論するので、実行速度は評価しない。

1. JavaがObjective Cより開発効率が高い7つの理由

Javaは、(1)ポータビリティ、(2)メモリ管理方式、(3)静的オブジェクト型、(4)コンストラクタと静的メンバー変数、(5)言語仕様の簡潔さ、(6)利用範囲の広さ、(7)利用者数と人気により、Objective Cよりも開発効率が良い。各項目の理由は以下になる。

1.1. ポータビリティ
互換性や移植性を意味するが、取り扱いのよさと考えて良いだろう。
Javaは仮想マシン(JVM)でバイト・コードを実行するため、互換性があると信じられている。実際はそれだけではなく、標準APIの充実も図られ、JVMを生かしてライブラリの取り扱いも工夫されている。つまり、OSのリンカーに依存しない。複数バージョンのJVMや、複数バージョンのライブラリを同じOSにインストールする事も容易だ。さらに、Javaの"Write once, run everywhere."は単なるキャッチコピーだが、プログラマにポータビリティを心がけさせる心理効果は大きい。JavaもJNIで環境依存コードはかけるが、好んで使うプログラマはほとんど見かけない。
Objective Cもソースコード・レベルで異機種互換性はとれるだろうが、標準APIは貧弱で、利用するライブラリやフレームワークの互換性も取れていない。例えばMacintoshで使われるCocoaフレームワークは、LinuxやWindowsでは標準的には使えない。また、Objective Cはネイティブ・コードを生成するのでOSのリンカーに依存する。つまり、Objective Cのソースコードがポータビリティのあるものでも、OSに応じた実行ファイルの生成手順が必要となる。
1.2. メモリ管理方式
オブジェクト指向プログラミングでは、オブジェクトの生成と破棄が大量に発生するため、付随したメモリー管理も煩雑になる。ゆえにメモリ管理は重要だ。
一般的に、JavaとObjective Cでは、Javaのメモリ管理の方がプログラマ負担が少ないとされる。具体的には、Macintosh OS XのObjective Cプログラマは以下のようなメモリ管理の工夫をしているが、Javaプログラマはしていない
  1. 自分で生成したオブジェクトは、自分で解放する。
  2. 他人が生成したオブジェクトは、気に留めない。
  3. 他人が生成したオブジェクトが必要なら、必ず保持(retain)して、必要にならなくなった時点で、必ず解除(release or autorelease)する。
  4. 可能な限り alloc-init系の生成メソッドは使わない。
  5. alloc、init…を使う場合は必ず autoreleaseを入れる。
出所) Memory Management of Cocoaより転載
Objective Cも、2.0からGCが搭載された。C互換のポインタを用いなければ、上記のような工夫を行わずにコーディングできる。ただしデフォルトではないので、クラス内などでGCが有効になっていることを前提にできない。iOSにはGCは使えないし、OS X用でもプログラマがGCを使っているかは分からないので、クラス設計者はGCが有効であることを前提にできない。つまり、GCのみを前提とできるJavaとは、依然として様相が異なる事になる。
1.3. 静的オブジェクト型
JavaやC++はオブジェクトが静的型だが、Objective Cは動的型だ。
オブジェクトが静的型であれば、コンパイル時にデータ構造が厳しくチェックされ、規律がつける事が可能になる。動的型である場合、コンパイル時にデータ構造のチェックが甘くなるため、プログラマの負担が増える可能性がある。
Javaであれば、ライブラリが定義した条件を満たした構造のデータしかパラメータとして渡せない。Objective Cも、コンパイラは型チェックをするが、動的に既存クラスにメソッドを追加できるため、コンパイル時のチェックは限定的になる。つまり、ある追加メソッドを持つクラスのインスタンスを引数として前提としたライブラリに、同一のクラスだが追加メソッドが無いインスタンスを引数として渡す事がありえる。
これは余談だが、実行速度の面では動的オブジェクト型の方が不利で、C++に比べてObjective Cが遅いと言われる理由になっている。
1.4. コンストラクタと静的メンバー変数
Objective Cのクラスには、コンストラクタと静的メンバー変数が無い。慣習的には、initメソッドをコンストラクタの代わりをし、グローバル変数で静的メンバー変数の代わりを行っているが、現代的なGoFデザイン・パターンが書きづらくなっている。
1.5. 言語仕様の簡潔さ
一般的にObjective CのC互換性は、Cプログラマへの親和性や、ライブラリの互換性などからアドバンテージだと考えられている。しかし、非オブジェクト指向プログラミングが同時に可能になるため、言語仕様が煩雑になっているデメリットもある。
例えば構造体を考えよう。Javaでは構造体は無いので、メモリ管理に関する演算子は、newしかない。Objective Cでは、malloc/calloc/freeなどの構造体用のメモリ管理関数群と、retain/copy/release/autorelease等のオブジェクト用メモリ管理メソッド群が存在する。2.0からはGCという選択肢も追加された。文字列型も文字コードが規定されない古いC関数群と、Foundationで提供されるNSStringクラスが共存している。また、Objective Cはポインターが使えるため、ポインターに付随する問題も残る事になる。
Javaは言語仕様としてマルチスレッドがサポートされているのも、全体の記述がすっきりさせる効果がある。マルチスレッドで必須になる排他処理も、当初から存在する。Objective CもOS X 10.3以降は@synchronizedがサポートされたが、それまでは文法的には排他処理機能は存在しなかった。
1.6. 利用範囲の広さ
Javaは次のように利用範囲が広い言語となっており、デスクトップやスマートフォンに限らず、Objcetive Cよりプログラマーの守備範囲を広げてくれる。
1.6.1. サーバーサイド
エンタープライズのウェブ・アプリケーションでは最も人気のある言語がJavaで、実用レベルでのJavaの普及のきっかけになったと言われる。Apple社のWebObjectsも過去にはObjective Cをサポートしていたが、現在ではJavaのみをサポートしている。
1.6.2. ケータイ
スマートフォン以前のフィーチャーフォンのケータイ・アプリでは、Javaは独占的な地位を得ている。Javaには『サンドボックス』と呼ばれる機能があり、実行時にAPIの規制をかけることができる。C++のケータイ・アプリ開発環境のBREWと違い、アプリの安全性確認や開発者の所在が業務的に必要でなく、迅速な開発が可能だ。
1.6.3. ブラウザー/ドキュメント
ブラウザー内のJava Appletは、セキュリティーのための制限が強すぎ、インタラクティブな機能がFlashより弱いために人気は無いが、ゲームなどで今でも見かける事がある。Flashには劣る結果となっているが、Objective Cでは同様の機能が無いため、アドバンテージの一つにあげることができるだろう。また、OpenOfficeのドキュメント内で利用が可能など、Applet自体の応用範囲はブラウザに限定されていない。
これら以外にも、Java Web Startや、米国防省で採用されたJava Cards等の利用形態もある。
1.7. 利用者数と人気
利用が進むとノウハウとライブラリがたまるので、利用者数と人気は重要なファクターの一つだが、Javaの人気は圧倒的で、Objective Cが太刀打ちできる見込みは薄い(マイコミジャーナル)。
Javaは1994年に発表されて以来、ずっと注目されてきたプログラミング言語で、サーバーサイドやケータイアプリに限らず、90年代後半からはSIerの新人研修で広く使われるなど利用者が多い。また、EclipseやNetBeansなどの人気の統合開発環境がJavaアプリケーションであるのも、土台を抑えている意味で人気があると言えるであろう。

2. 評価しなかった点

一般的にJavaのアドバンテージとされる、開発環境は評価を避けた。統合開発環境はJava/EclipseがObjective C/Xcodeを上回るとの声もあったが、EclipseでObjective Cの開発もできるため評価は避けた。また、JavaにはantやJUnitなどの開発支援ツールもあるが、Objective CにもUnitKitがあり優劣をつけづらい。

3. 分析での留意点

定量的な分析が不可能であるため、異論は残る事は認識している。1.1節ポータビリティと1.2節メモリ管理については比較的同意を得やすいと思うが、1.3節と1.4節は多人数で複雑なアプリケーションを書くまでは問題にならないであろうし、1.5節はCの機能を使わないことが徹底できれば何も問題が無い。1.6節に関しては、よりハードウェアに近いデバイス・ドライバの作成については、一般にはC/C++が使われるだろうが、Objective Cの方が有利かも知れない。1.7節に関しても、力のあるプログラマならば流行廃りとはあまり関係なく利用ができるため、問題にならない人も多いであろう。

4. まとめ

結論はJavaの開発効率が高いという平凡なものだが、それを主張する人でも根拠を明確にしない事が多いため、多少は意味があるとは思う。

最後にObjective Cに対するJavaの優位点をまとめる。Javaはポータビリティとメモリ管理方式に優れており、静的オブジェクト型とコンストラクタと静的メンバー変数があり言語仕様が洗練されている一方で、簡潔でもある。さらに利用範囲が広くプログラマーにとって利便性が高く、利用者数も人気もあるため情報収集が容易だ。ゆえに、JavaはObjective Cに対して開発効率が高いと言える。

0 コメント:

コメントを投稿