From dabd17577b3fe025c518b53d156c691e2f39f121 Mon Sep 17 00:00:00 2001 From: Martin Soenen Date: Tue, 22 Sep 2026 22:21:18 +0200 Subject: [PATCH] :zap: Check the IDE mixin once per extension initialization Faker builds a fresh Container for every generated value, and the constructor checked the mixin manifest each time: is_file() plus a filemtime() on the mixin, vendor/composer/installed.json and the project composer.json. Several filesystem stats per $faker->name(). The mixin describes the registered extensions, so it only needs checking when they are initialized. forgetExtensions() still triggers a new check, since the next Container initializes them again. Throughput on PHP 8.4 (calls per second, benchmarks/ from #feat/benchmarks): name 82k -> 210k, email 58k -> 102k, number 111k -> 574k, sentences 68k -> 160k, dateTime 91k -> 243k. --- src/Container/Container.php | 8 +++++--- tests/Unit/ContainerMixinManifestTest.php | 22 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Container/Container.php b/src/Container/Container.php index 293297c..076ad1a 100644 --- a/src/Container/Container.php +++ b/src/Container/Container.php @@ -58,10 +58,12 @@ public function __construct(bool $shouldBuildContainerMixin = true) $this->registerConfiguredProviders(); $this->bootstrap(); - } - if ($shouldBuildContainerMixin) { - $this->buildContainerMixinManifest(); + // The mixin describes the registered extensions, so it only needs checking when they are + // initialized: checking it on every call costs several filesystem stats per generated value. + if ($shouldBuildContainerMixin) { + $this->buildContainerMixinManifest(); + } } } diff --git a/tests/Unit/ContainerMixinManifestTest.php b/tests/Unit/ContainerMixinManifestTest.php index 6dce686..6d0dc63 100644 --- a/tests/Unit/ContainerMixinManifestTest.php +++ b/tests/Unit/ContainerMixinManifestTest.php @@ -154,4 +154,26 @@ public function testNoExtension() $this->assertFileExists('/tmp/ContainerMixin.php'); } + + public function testContainerMixinIsOnlyCheckedWhenExtensionsAreInitialized() + { + $container = new \Xefi\Faker\Container\Container(shouldBuildContainerMixin: false); + $container->forgetExtensions(); + $container->forgetBootstrappers(); + @unlink('/tmp/ContainerMixin.php'); + + new \Xefi\Faker\Container\Container(); + $this->assertFileExists('/tmp/ContainerMixin.php'); + + unlink('/tmp/ContainerMixin.php'); + new \Xefi\Faker\Container\Container(); + $this->assertFileDoesNotExist('/tmp/ContainerMixin.php'); + + $container->forgetExtensions(); + $container->forgetBootstrappers(); + new \Xefi\Faker\Container\Container(); + $this->assertFileExists('/tmp/ContainerMixin.php'); + + unlink('/tmp/ContainerMixin.php'); + } }