From 7bd2854d538cdcd021b1697aec23b0afa405aa92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Andr=C3=A9?= Date: Sun, 3 Nov 2024 15:34:50 +0100 Subject: [PATCH] Improve __toString performance Running scenario: Short attributes, empty rendered __toString() time: 0.00077986717224121 seconds __toString2() time: 0.00049495697021484 seconds Improvement: 36.533170284317% Running scenario: Short attributes, partial rendered __toString() time: 0.00054383277893066 seconds __toString2() time: 0.00031709671020508 seconds Improvement: 41.692240245506% Running scenario: Short attributes, full rendered __toString() time: 0.00030899047851562 seconds __toString2() time: 0.00012898445129395 seconds Improvement: 58.256172839506% Running scenario: Long attributes, empty rendered __toString() time: 0.0038020610809326 seconds __toString2() time: 0.0026099681854248 seconds Improvement: 31.353859660124% Running scenario: Long attributes, partial rendered __toString() time: 0.0032980442047119 seconds __toString2() time: 0.0022611618041992 seconds Improvement: 31.439311790646% Running scenario: Long attributes, full rendered __toString() time: 0.00074219703674316 seconds __toString2() time: 0.00014185905456543 seconds Improvement: 80.886604561516% --- src/TwigComponent/src/ComponentAttributes.php | 79 +++++++++---------- 1 file changed, 37 insertions(+), 42 deletions(-) diff --git a/src/TwigComponent/src/ComponentAttributes.php b/src/TwigComponent/src/ComponentAttributes.php index 39213d945f..bea7876dfd 100644 --- a/src/TwigComponent/src/ComponentAttributes.php +++ b/src/TwigComponent/src/ComponentAttributes.php @@ -37,48 +37,43 @@ public function __construct(private array $attributes) public function __toString(): string { - return array_reduce( - array_filter( - array_keys($this->attributes), - fn (string $key) => !isset($this->rendered[$key]) - ), - function (string $carry, string $key) { - if ( - str_contains($key, ':') - && preg_match(self::NESTED_REGEX, $key) - && !preg_match(self::ALPINE_REGEX, $key) - && !preg_match(self::VUE_REGEX, $key) - ) { - return $carry; - } - - $value = $this->attributes[$key]; - - if ($value instanceof \Stringable) { - $value = (string) $value; - } - - if (!\is_scalar($value) && null !== $value) { - throw new \LogicException(\sprintf('A "%s" prop was passed when creating the component. No matching "%s" property or mount() argument was found, so we attempted to use this as an HTML attribute. But, the value is not a scalar (it\'s a "%s"). Did you mean to pass this to your component or is there a typo on its name?', $key, $key, get_debug_type($value))); - } - - if (null === $value) { - trigger_deprecation('symfony/ux-twig-component', '2.8.0', 'Passing "null" as an attribute value is deprecated and will throw an exception in 3.0.'); - $value = true; - } - - if (true === $value && str_starts_with($key, 'aria-')) { - $value = 'true'; - } - - return match ($value) { - true => "{$carry} {$key}", - false => $carry, - default => \sprintf('%s %s="%s"', $carry, $key, $value), - }; - }, - '' - ); + $attributes = ''; + + foreach ($this->attributes as $key => $value) { + if (isset($this->rendered[$key])) { + continue; + } + + if ( + str_contains($key, ':') + && preg_match(self::NESTED_REGEX, $key) + && !preg_match(self::ALPINE_REGEX, $key) + && !preg_match(self::VUE_REGEX, $key) + ) { + continue; + } + + if (null === $value) { + trigger_deprecation('symfony/ux-twig-component', '2.8.0', 'Passing "null" as an attribute value is deprecated and will throw an exception in 3.0.'); + $value = true; + } + + if (!\is_scalar($value) && !($value instanceof \Stringable)) { + throw new \LogicException(\sprintf('A "%s" prop was passed when creating the component. No matching "%s" property or mount() argument was found, so we attempted to use this as an HTML attribute. But, the value is not a scalar (it\'s a "%s"). Did you mean to pass this to your component or is there a typo on its name?', $key, $key, get_debug_type($value))); + } + + if (true === $value && str_starts_with($key, 'aria-')) { + $value = 'true'; + } + + $attributes .= match ($value) { + true => ' '.$key, + false => '', + default => \sprintf(' %s="%s"', $key, $value), + }; + } + + return $attributes; } public function __clone(): void