Java開発においてコードの実行速度を向上させるための実践的なテクニックを紹介します。
- システムリソースのプーリング活用(データベース接続、スレッドなど)
スタンドアロンアプリケーションでは、C3P0、Proxool、DBCPなどのオープンソース接続プール実装を使用できます。コンテナ上で動作するアプリケーションでは、サーバーが提供するDataSourceを利用できます。スレッドプールには、JDK標準のjava.util.concurrent.ExecutorServiceが利用可能です。
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class ThreadPoolExample {
public static void main(String[] args) {
// スレッドプールの作成
ExecutorService service = Executors.newFixedThreadPool(2);
// タスクの作成
Runnable taskA = new CustomTask();
Runnable taskB = new CustomTask();
Runnable taskC = new CustomTask();
Runnable taskD = new CustomTask();
Runnable taskE = new CustomTask();
// タスクの実行
service.execute(taskA);
service.execute(taskB);
service.execute(taskC);
service.execute(taskD);
// プールのシャットダウン
service.shutdown();
}
}
class CustomTask implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + "を実行中...");
}
}
- ネットワークオーバーヘッドの削減
データベースやリモートサービスとのやり取りでは、複数回の呼び出しを単一の呼び出しに統合することで、ネットワーク負荷を軽減できます。
- 頻繁にアクセスする外部リソースのメモリキャッシュ
アプリケーション起動時に静的なHashMapを利用してリソースを読み込む簡単な方法や、OSCache、Ehcacheなどのオープンソースキャッシュフレームワークの使用が可能です。リソースとの同期には、定期的なポーリングや外部リソース更新時の能動的通知、または手動同期用のインターフェース(コマンド方式やUI方式)を実装する方法があります。
- I/O操作の最適化
Javaのファイル操作にはInputStream/OutputStreamとReader/Writerの2種類があります。ストリーム方式の方が高速で、後者は主に文字操作用です。文字がASCIIのみの場合はストリーム方式を使用することで効率が向上します。
JDK1.4以降のNIOはIOよりも効率的です。
OutputStream output = new BufferedOutputStream(new FileOutputStream(new File("d:/data.txt")));
output.write("テストデータ".getBytes());
output.flush();
output.close();
BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriterを利用して、ディスクへの直接アクセス回数を削減できます。
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while (bufferedReader.readLine() != null) {
counter++;
}
- オブジェクトの頻繁な生成を避ける
アプリケーション全体で単一インスタンスのみが必要なクラスには、シングルトンパターンを適用します。
- 文字列連結操作の最適化
文字列の連結には、StringBufferまたはStringBuilderを使用します。
- ユーティリティクラスは静的メソッドでアクセス
例外はメソッド終了を制御できますが、スタックトレースの保持はパフォーマンスを消費します。不要なinstanceofによる条件判断は避け、より効率的な条件判断方法を使用します。
- 効率的なJavaクラスの選択
例えば、ArrayListはVectorよりもパフォーマンスに優れています。
- 設計段階からのパフォーマンス考慮
システムのパフォーマンスは、システム分析と設計の初期段階から考慮する必要があります。
結論として、システム実行時のパフォーマンスは、CPU、メモリ、I/Oの3つの主要な側面から最適化を検討します。不要なCPU消費を減らし、不要なI/O操作を削減し、メモリ利用効率を向上させることが重要です。