Skip to content

Conversation

soyuka
Copy link
Contributor

@soyuka soyuka commented Aug 25, 2025

Q A
Branch? 7.4
Bug fix? no
New feature? yes
Deprecations? no
Issues n/a
License MIT

needs #61497

(code-gen ✗)❯ /home/linuxbrew/.linuxbrew/Cellar/php/8.4.11/bin/php ./vendor/bin/phpbench run
PHPBench (84.x-dev) running benchmarks... #standwithukraine
with configuration file: /home/soyuka/forks/symfony/src/Symfony/Component/ObjectMapper/phpbench.json
with PHP version 8.4.11, xdebug ✔, opcache ❌

\Symfony\Component\ObjectMapper\Benchmarks\ObjectMapperBench

    benchObjectMapper.......................I4 - Mo268.351μs (±0.86%)
    benchCachedObjectMapper.................I4 - Mo134.417μs (±0.41%)

Subjects: 2, Assertions: 0, Failures: 0, Errors: 0
Benchmark code
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\ObjectMapper\Benchmarks;

use PhpBench\Attributes as Bench;
use Symfony\Component\ObjectMapper\CachedObjectMapper;
use Symfony\Component\ObjectMapper\ObjectMapper;
use Symfony\Component\ObjectMapper\Tests\Fixtures\A;
use Symfony\Component\ObjectMapper\Tests\Fixtures\C;
use Symfony\Component\ObjectMapper\Tests\Fixtures\D;

#[Bench\BeforeMethods('setUp')]
class ObjectMapperBench
{
    private ObjectMapper $objectMapper;
    private CachedObjectMapper $cachedObjectMapper;
    private A $sourceObject;
    private string $cacheDir;

    public function setUp(): void
    {
        $this->objectMapper = new ObjectMapper();
        $this->cacheDir = sys_get_temp_dir() . '/symfony_object_mapper_bench_' . uniqid();
        $this->cachedObjectMapper = new CachedObjectMapper($this->cacheDir);

        $d = new D(baz: 'foo', bat: 'bar');
        $c = new C(foo: 'foo', bar: 'bar');
        $this->sourceObject = new A();
        $this->sourceObject->foo = 'test';
        $this->sourceObject->transform = 'test';
        $this->sourceObject->baz = 'me';
        $this->sourceObject->notinb = 'test';
        $this->sourceObject->relation = $c;
        $this->sourceObject->relationNotMapped = $d;
    }

    public function tearDown(): void
    {
        if (is_dir($this->cacheDir)) {
            array_map('unlink', glob($this->cacheDir . '/*'));
            rmdir($this->cacheDir);
        }
    }

    #[Bench\Revs(100)]
    #[Bench\Iterations(5)]
    public function benchObjectMapper(): void
    {
        $this->objectMapper->map($this->sourceObject);
    }

    #[Bench\Warmup(1)]
    #[Bench\Revs(100)]
    #[Bench\Iterations(5)]
    public function benchCachedObjectMapper(): void
    {
        $this->cachedObjectMapper->map($this->sourceObject);
    }
}

@fabpot
Copy link
Member

fabpot commented Aug 27, 2025

#61497 has been merged now.

@mtarld
Copy link
Contributor

mtarld commented Aug 27, 2025

@soyuka maybe you can leverage the Filesystem component like it has been done in the JsonStreamer?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some comments.
I'd be great to have a few fixtures of generated files.
Next steps are cache warmups (#61528 could be used for inspiration)
and FrameworkBundle integration of course.
Up to continue that way?

@soyuka soyuka force-pushed the code-gen branch 2 times, most recently from 8d7e35c to 3d52bc3 Compare September 12, 2025 09:17
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, here are some minor stuff, LGTM after that!

return null;
}

public static function call(callable $fn, mixed $value, object $source, ?object $target = null): mixed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this helper? why not doing this instead? what's special about string callables?
$fn($value, $source, $target)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because we'll give $source and $target to a function that probably do not handle that (ucfirst for example). Maybe it was not a good idea to support native php functions afterall and we should only supports callables?

@soyuka
Copy link
Contributor Author

soyuka commented Sep 12, 2025

@nicolas-grekas I extracted the part dumping code to another class in Internal, it was better for the cache warmer. I resolved the previous points, some code has just moved to the generator. As it has a direct impact on the CachedObjectMapper implementation I merged the cache warmer into this PR.

@soyuka soyuka force-pushed the code-gen branch 2 times, most recently from fb21219 to 8bf4b10 Compare September 12, 2025 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants