きっかけ
面接でTypeScriptの説明を求められ型付けを中心に説明したが、「Javaとどう違うのか?」と聞かれた時に答えられなかった。確かにJavaでのWebアプリ案件も見かける。
そこでTypeScriptとJavaの違いを調べてみた。
型付けに関して基本同じで、以下が大きく違っていた:
- Webアプリ開発の準備時間
- 起動速度
- 実行速度の特性
Webアプリの準備まで
TypeScriptの場合
<!-- 5分で動くWebアプリ -->
<html>
<body>
<h1>Hello World</h1>
<script>
console.log("すぐに動く!");
</script>
</body>
</html>
Javaの場合
簡単なWebアプリを作るには...
// 1. Maven/Gradle設定
// 2. Spring Boot依存関係
// 3. Controller作成
// 4. Thymeleafテンプレート
// 5. CSS/JavaScript追加
最低でも数日〜数週間
→ この準備時間の差が、開発効率に大きな影響を与える。
速度
起動速度
実際の起動時間を測定してみた:
# TypeScript/Node.js
$ time node app.js
Hello World
real 0m0.134s # 約0.1秒で起動
# Java
$ time java HelloWorld
Hello World
real 0m0.432s # 約0.4秒で起動(3-4倍遅い)
なぜJavaの起動が遅いのか?
JVM(Java仮想マシン)の初期化
- クラスローダーの準備
- メモリ領域の確保
- ガベージコレクターの初期化
クラスファイルの読み込み
- .classファイルの検索・読み込み
- 依存関係の解決
- バイトコード検証
各言語の初期化処理比較
言語 | クラスローダー | ガベージコレクター | メモリ管理 | 起動速度 |
---|---|---|---|---|
Java | ✅(重い) | ✅(重厚) | JVM管理 | 遅い |
TypeScript | - (存在しない) | ✅(軽量) | V8任せ | 高速 |
C言語 | - (存在しない) | - (存在しない) | OS任せ | 最速 |
※メモリ領域などが出てきたのでC言語も対象に入れてみた。ちなみにCはガベージコレクター存在しないとあるが、それは手動で行なう必要がある
→TypeScriptは「ガベージコレクター」と「メモリ領域確保」はあるが、クラスローダーがないため、Javaほど重い初期化処理は不要。
実行速度
長時間実行(数分〜数時間のタスク)では、興味深い逆転現象が起こる。
Java の JIT(Just-In-Time)コンパイル効果
実行時間経過 → パフォーマンス変化
0秒 : Java起動(遅い)
1-10秒 : インタープリター実行(Node.jsと同程度)
10秒以降: JITコンパイル効果で大幅高速化
実際のベンチマーク例:
処理時間1分のタスク:
Node.js: 60秒
Java: 45秒(JIT効果で25%高速化)
処理時間10分のタスク:
Node.js: 600秒
Java: 420秒(JIT効果で30%高速化)
V8もJITを使ってるのになぜJavaの方が速い?
確かにNode.jsのV8エンジンもJITコンパイルを使っている:
JavaScript → V8エンジン → 機械語
├── 即座に実行開始(JITコンパイル)
├── 軽量ランタイム
└── イベントループによる効率的I/O
しかし、JITの質が大きく異なる:
プロファイリング期間の違い
V8 (Node.js):
├── 数秒〜数十秒でJIT最適化
├── Webアプリの短時間レスポンス重視
└── 早期最適化でユーザー体験向上
HotSpot (Java):
├── 数分〜数十分かけてプロファイリング
├── サーバーアプリの長時間実行重視
└── 時間をかけた詳細な最適化
最適化レベルの違い
V8の制約(動的型付け)
function add(a, b) {
return a + b; // a, bが何の型か実行時まで不明
}
// V8は推測でJITコンパイル
add(5, 3); // 整数として最適化
add("hello", "world"); // 文字列に再最適化(逆最適化発生)
Java HotSpotの優位性(静的型付け)
public int add(int a, int b) {
return a + b; // 型が確定している
}
// JITコンパイラは確実に整数演算として最適化可能
// 逆最適化のリスクなし
// より攻撃的な最適化が可能
実行回数による最適化レベル
実行回数 | V8の最適化 | HotSpotの最適化 |
---|---|---|
1-99回 | インタープリター | インタープリター |
100-999回 | 軽量JIT最適化 | 軽量JIT (C1) |
1,000-9,999回 | 中程度最適化 | 中程度最適化 |
10,000回以上 | 最大最適化完了 | 重厚JIT (C2) 開始 |
100,000回以上 | --- | 超高度最適化継続 |
長時間実行におけるJavaの速度優位性は、**「時間をかけてでも最高の最適化を追求する」**という設計思想の結果だった。
速度まとめ
- 起動速度: TypeScript(軽量な初期化)
- 短時間実行: TypeScript(早期最適化)
- 長時間実行: Java(重厚なJIT最適化)
- 開発速度: TypeScript(簡単な環境構築)
まとめ
面接では「用途に応じた使い分け」という観点で答えられれば良かったのかもしれない。TypeScriptはWebアプリの迅速な開発に、Javaはエンタープライズシステムの高性能処理に、それぞれ最適化されているのだと理解。