Slim4 DI container cache / route cache er cache / route cache
https://www.slimframework.com/docs/v4/objects/routing.html#route-expressions-caching
[index.php]
...
// Instantiate PHP-DI ContainerBuilder
$containerBuilder = new ContainerBuilder();
/**[DI container Cache★]
* Compile the container for optimum performances.
* Should be set to true in production
*/
if (true) {
$containerBuilder->enableCompilation(__DIR__ . '/../temp/cache');
}
...
//Instantiate the app
$app = AppFactory::create();
/**[Router Cache★]
* To generate the route cache data, you need to set the file to one that does not exist in a writable directory.
* After the file is generated on first run, only read permissions for the file are required.
* You may need to generate this file in a development environment and committing it to your project before deploying
* if you don't have write permissions for the directory where the cache file resides on the server it is being deployed to
*/
$routeCollector = $app->getRouteCollector();
$routeCollector->setCacheFile(__DIR__ . '/../temp/cache/router_cache.file');
[DI container Cache★]
dependencies.php 컨테이너에 정의한 함수들이 => temp/cache 폴더안에 아래 CompiledContainer.php 파일로 생성됨
원래 [dependencies.php] 내용
<?php
/**
* Dependency Injection in Slim 4
*/
declare(strict_types=1);
use DI\ContainerBuilder;
return function (ContainerBuilder $containerBuilder) {
$containerBuilder->addDefinitions([
//DiTestService::class
DiTestService1::class => function () {
return 100;
},
//DiTestService2::class
DiTestService2::class => function () {
return 200;
}
]);
};
/**
* DiTestService1::class 호출방법
* $result = $this->get(DiTestService2::class);
*/
▼
temp/cache 폴더안에 아래 CompiledContainer.php 파일 생성됨
(실제 publish 할때, 컨테이너 소스변경 되었을때는 CompiledContainer.php 삭제하여 최신 재 생성 함)
생성된 [CompiledContainer.php]
<?php
/**
* This class has been auto-generated by PHP-DI.
*/
class CompiledContainer extends DI\CompiledContainer{
const METHOD_MAPPING = array (
'DiTestService1' => 'get1',
'DiTestService2' => 'get2',
);
protected function get1()
{
return $this->resolveFactory(static function () {
return 100;
}, 'DiTestService1');
}
protected function get2()
{
return $this->resolveFactory(static function () {
return 200;
}, 'DiTestService2');
}
}
[Router Cache★]
routes.php 에서 정의한 라우터 분기 함수들이 => /temp/cache/router_cache.file 파일에 생성됨
(실제 publish 할때, 라우터가 변경되었을때 router_cache.file 삭제하여 최신 재 생성 함, publish 서버 /temp/cache/... 폴더는 읽기전용으로 함)
원래 [routes.php]
<?php
use Slim\App;
return function (App $app) {
//DELETE
$app->delete('/d/id/{id}', Slim\AC\Fu\DeleteByIdAction::class);
//테스트용 라우터 생성
for ($i = 1; $i <= 100; $i++) {
$app->get("/$i/{id:\d+}", Slim\AC\Fu\DeleteByIdAction::class);
$app->post("/$i/{id:\d+}", Slim\AC\Fu\DeleteByIdAction::class);
$app->put("/$i/{id:\d+}", Slim\AC\Fu\DeleteByIdAction::class);
$app->delete("/$i/{id:\d+}", Slim\AC\Fu\DeleteByIdAction::class);
}
};
▼ /temp/cache/router_cache.file 파일에 생성된 라우터 캐시
<?php
return array (
...........
0 =>
'GET' =>
array (
2 =>
array (
0 => 'route6',
1 =>
array (
'id' => 'id',
),
),
3 =>
array (
0 => 'route10',
1 =>
array (
'id' => 'id',
),
),
4 =>
array (
0 => 'route14',
1 =>
array (
'id' => 'id',
),
),
5 =>
...........
Cache 사용할 때 효과
[테스트 조건]
routes.php 라우터 파일에 테스트용으로 400개 및 4000개의 라우터 경로 정의
(SelectAllAction::class 는 실제 호출되는 시점에만 해당 클래스(컨트롤러)에서 __invoke 로직 실행됨, 라우터 캐시와 무관)
for ($i = 1; $i <= 100; $i++) {
$app->get("/$i/{id:\d+}", Slim\AC\Fu\SelectAllAction::class);
$app->post("/$i/{id:\d+}", SSlim\AC\Fu\SelectAllAction::class);
$app->put("/$i/{id:\d+}", Slim\AC\Fu\SelectAllAction::class);
$app->delete("/$i/{id:\d+}", Slim\AC\Fu\SelectAllAction::class);
}
[테스트 결과]
라우터 캐시 미사용 상태에서 POSTMAN으로 10번 호출 결과
라우터400개 | 라우터4000개
------------------------
80ms 107ms
83ms 114ms
57ms 90ms
55ms 89ms
66ms 78ms
57ms 94ms
65ms 80ms
56ms 79ms
64ms 79ms
54ms 84ms
------------|-----------
평균 63.7ms 89.4ms
라우터 캐시 활성화 상태에서 POSTMAN으로 10번 호출 결과
라우터400개 | 라우터4000개
---------------------------
82ms 100ms
74ms 76ms
59ms 69ms
53ms 68ms
62ms 67ms
55ms 77ms
55ms 67ms
63ms 67ms
61ms 93ms
55ms 65ms
------------|----------
평균 61.9ms 74.9ms
1. 라우터 캐시 사용 시 수치 상 응답 속도 개선이 있다.
2. 라우터 수가 50~100개 정도 일 경우 체감 상 응답 속도에 큰 차이가 없다.
3. 미리 array 형태로 해석된 캐시가 사용되므로 단순히 응답 속도 외에도 빠른 연산에 이점이 있을 수 있어 라우터 캐시 사용.
[참고]
위 Slim4(slim/slim) 에 포함된 라우터 캐시는 nikic/fast-route 를 사용하고 있음.
https://github.com/nikic/FastRoute