はじめに
Laravelで開発していると、インスタンスを作成する場合は依存性注入(Dependency Injection DI)を使用することが推奨されていて、コントローラー内で同じクラスを何度もインスタンス化することは避けられています。
しかし、毎回インスタンス化するのは非効率だという話を聞くけど、具体的にどう非効率なのか気になったので検証してみました。
今回は、依存性注入(DI)を使う場合と使わない場合で、メモリ消費量と処理時間を比較してみます。
検証環境
Laravel 11系
PHP 8系
Docker環境上で実行
テストコード
テスト対象となる MyService クラスを用意する。
namespace App\MyClasses;
class MyService
{
public function someMethod()
{
return true;
}
}
続いて、コントローラーにテストコードを書く。
namespace App\Http\Controllers;
use App\MyClasses\MyService;
class PostController extends Controller
{
public function index(MyService $myservice)
{
// 依存性注入なし
$startMemoryNonDI = memory_get_usage();
$startTimeNonDI = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$object = new MyService();
$object->someMethod();
}
$endMemoryNonDI = memory_get_usage();
$endTimeNonDI = microtime(true);
$msgNonDI[] = 'Memory used: ' . ($endMemoryNonDI - $startMemoryNonDI) . ' bytes';
$msgNonDI[] = 'Time taken: ' . ($endTimeNonDI - $startTimeNonDI) . ' seconds';
// 依存性注入あり
$startMemoryDI = memory_get_usage();
$startTimeDI = microtime(true);
for ($i = 0; $i < 1000; $i++) {
$myservice->someMethod();
}
$endMemoryDI = memory_get_usage();
$endTimeDI = microtime(true);
$msgDI[] = 'Memory used: ' . ($endMemoryDI - $startMemoryDI) . ' bytes';
$msgDI[] = 'Time taken: ' . ($endTimeDI - $startTimeDI) . ' seconds';
$data = [
'NonDI' => $msgNonDI,
'DI' => $msgDI,
];
return view('post.index', $data);
}
}
検証結果
テスト | メモリ使用量 (bytes) | 処理時間 (seconds) |
---|---|---|
NonDI | 80 bytes | 0.0346479 seconds |
DI | 0 bytes | 0.0144579 seconds |
結果分析
メモリ使用量の違い:NonDI では毎回インスタンス化するためメモリを消費するが、DI では同じインスタンスを使い回すため消費が 0 になる。
処理時間の違い:NonDI は 1000 回のインスタンス化処理が発生するため、処理時間が長くなる。
まとめ
コントローラー内で同じクラスを 何度もインスタンス化するのは非効率 であることが確認できました。
特に、処理回数が多くなるとパフォーマンスに影響が出やすいようですね。
Laravelの 依存性注入(DI) を使うことで、効率的に同じインスタンスを再利用できます。
DI を使わない場合のデメリットを実際に検証することで理解が深まりましたので、継続して学んでいきたいです!