Skip to content

Commit

Permalink
Improve __toString performance
Browse files Browse the repository at this point in the history
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%
  • Loading branch information
smnandre committed Nov 3, 2024
1 parent cb7809f commit 7bd2854
Showing 1 changed file with 37 additions and 42 deletions.
79 changes: 37 additions & 42 deletions src/TwigComponent/src/ComponentAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 7bd2854

Please # to comment.