Skip to content

Large enums are slow #11968

@SamMousa

Description

@SamMousa

Bug report

I'm trying out a new approach to icons.
Gist here: https://gist.github.com/SamMousa/786b5eb6c8f9d8b6d1aa8aca658f793b

tldr; this is an UnitEnum that has ~ 7500 cases.

It contains the SVG data for ~7500 icons. It's size is 3.1MB and it has ~15000 lines.
Initially I generated this as a BackedEnum, which essentially breaks PHPStorm. I tried it as a UnitEnum and this works well for code completion.

Note: while this approach might seem inefficient it is highly cachable. The Enum will live in PHP-FPMs opcode cache and data, strings, will live in the interned string cache.

Now we enter phpstan.

The enum essentially looks like this:

enum Mdi {
    case FileArrowUpDownOutline;
    case ChevronDownBoxOutline;

    public function svg(string $classes = '', array $extraAttributes = []): string
    {
        return Html::tag(
            'svg',
            $this->data(),
            [
                    'xmlns' => "http://www.w3.org/2000/svg",
                        'viewBox' => "0 0 24 24",
                    'fill' => 'currentColor',
                    'aria-hidden' => "true",
                    'class' => $classes,
                ...$extraAttributes
            ]
        );
    }

    private function data():string {
        return match($this) {
            self::FileArrowUpDownOutline => '<path d="M13.09 20C13.21 20.72 13.46 21.39 13.81 22H6C4.89 22 4 21.11 4 20V4C4 2.9 4.89 2 6 2H14L20 8V13.09C19.67 13.04 19.34 13 19 13C18.66 13 18.33 13.04 18 13.09V9H13V4H6V20H13.09M17 15L14.5 18H16V22H18V18H19.5L17 15M22 20V16H20V20H18.5L21 23L23.5 20H22Z" />',
            self::ChevronDownBoxOutline => '<path d="M19,3H5A2,2 0 0,0 3,5V19C3,20.11 3.9,21 5,21H19C20.11,21 21,20.11 21,19V5A2,2 0 0,0 19,3M19,19H5V5H19V19M7.41,8.29L12,12.88L16.59,8.29L18,9.71L12,15.71L6,9.71L7.41,8.29Z" />',
            
     
    }

Previous issues on big files talked about code complexity, however the complexity of this file is (or seems) very low.

Any pointers on how I could delve into the internals to look at improving performance would be greatly appreciated.
I'm even considering creating a stub and then ignoring the concrete implementation in config.

Code snippet that reproduces the problem

No response

Expected output

N/A

Did PHPStan help you today? Did it make you happy in any way?

As always, it's my best friend when refactoring code!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions