di: Fall back to autoloader when class is not in container

Currently there’s a need to declare everything that is repetitive if we need to set a single class without an interface into container:

\App\ConsoleCommand\CreateUser::class => \App\ConsoleCommand\CreateUser::class,

In such cases we can try to fall back to class autoloading.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 19 (18 by maintainers)

Most upvoted comments

  1. Were the tests conducted with composer autoloader optimized?

Yes. I used:

composer install --optimize-autoloader
  1. Triggering autoload is, of course, slower but I think we can ignore it in this case because has() is rarely used by itself. Usually it’s get().

Ok, I also think that we can ignore this, because these are fractions of microseconds.

  1. There’s a usage that should be checked in Factory: https://github.com/yiisoft/factory/blob/master/src/Factory.php#L55

Ok, I’ll check it too.

@samdark I just created benchmarks for method Container::has(). See #90.

Test N1

Method Containter::has() implementation (current):

    public function has($id): bool
    {
        return isset($this->definitions[$id]);
    }

Bench results:

$ ./vendor/bin/phpbench run --filter=MethodHas
PhpBench 0.14.0 (@git_version@). Running benchmarks.
Using configuration file: /yii-dev/dev/di/phpbench.json

\Yiisoft\Di\Tests\Benchmark\ContainerMethodHasBench

    benchPredefinedExisting       I4 P0 	[μ Mo]/r: 0.070 0.070 (μs) 	[μSD μRSD]/r: 0.001μs 1.66%
    benchUndefinedExisting        R2 I3 P0 	[μ Mo]/r: 0.071 0.071 (μs) 	[μSD μRSD]/r: 0.001μs 1.38%
    benchUndefinedNonexistent     R3 I4 P0 	[μ Mo]/r: 0.069 0.068 (μs) 	[μSD μRSD]/r: 0.002μs 2.25%

3 subjects, 15 iterations, 3,000 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 0.068 [0.070 0.070] 0.072 (μs)
⅀T: 1.052μs μSD/r 0.001μs μRSD/r: 1.761%

Test N2

Method Containter::has() implementation (proposed):

    public function has($id): bool
    {
        return isset($this->definitions[$id]) || (is_string($id) && class_exists($id));
    }

Bench results:

$ ./vendor/bin/phpbench run --filter=MethodHas
PhpBench 0.14.0 (@git_version@). Running benchmarks.
Using configuration file: /yii-dev/dev/di/phpbench.json

\Yiisoft\Di\Tests\Benchmark\ContainerMethodHasBench

    benchPredefinedExisting       I4 P0 	[μ Mo]/r: 0.071 0.071 (μs) 	[μSD μRSD]/r: 0.001μs 1.65%
    benchUndefinedExisting        R2 I3 P0 	[μ Mo]/r: 0.361 0.364 (μs) 	[μSD μRSD]/r: 0.008μs 2.21%
    benchUndefinedNonexistent     R1 I2 P0 	[μ Mo]/r: 0.538 0.527 (μs) 	[μSD μRSD]/r: 0.016μs 2.93%

3 subjects, 15 iterations, 3,000 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 0.069 [0.323 0.321] 0.072 (μs)
⅀T: 4.846μs μSD/r 0.008μs μRSD/r: 2.261%
  1. Were the tests conducted with composer autoloader optimized?
  2. Triggering autoload is, of course, slower but I think we can ignore it in this case because has() is rarely used by itself. Usually it’s get().
  3. There’s a usage that should be checked in Factory: https://github.com/yiisoft/factory/blob/master/src/Factory.php#L55