Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.4] Low-hanging optimization in Eloquent model #17739

Merged
merged 1 commit into from
Feb 3, 2017
Merged

[5.4] Low-hanging optimization in Eloquent model #17739

merged 1 commit into from
Feb 3, 2017

Conversation

fernandobandeira
Copy link
Contributor

@fernandobandeira fernandobandeira commented Feb 2, 2017

Re-submit of #17656

Changed just getAttributeFromArray so we keep the current behavior...

function foo() {
    $data = ['key' => null];
    if (array_key_exists('key', $data)) {
        // return $data['key'], which is null
    }
}

function bar() {
    $data = ['key' => null];
    if (isset($data['key'])) {
        // not reached
    }
    // return implicit null
}

We are saving around 5% with this change...

props @silwerclaw
also ping @vlakoff

@browner12
Copy link
Contributor

In the case of an attribute being null, do we need an explicit return null at the end, or is that implied?

@fernandobandeira
Copy link
Contributor Author

Thats implied

@GrahamCampbell
Copy link
Member

GrahamCampbell commented Feb 2, 2017

In the case of an attribute being null, do we need an explicit return null at the end, or is that implied?

Yeh, that's not needed. The introduction of the void return type into the language is just a confusion, since returning nothing is treated as null.

@browner12
Copy link
Contributor

thanks guys. looks like the behavior is identical then.

i can't speak to the speed savings, though.

@fernandobandeira
Copy link
Contributor Author

fernandobandeira commented Feb 2, 2017

Here's a gist that vlakoff did to benchmark it:

https://gist.github.com/vlakoff/2569a9de8b33b05a203f6993ec39e69b

You can modify to apply just the change on getAttributeFromArray

@taylorotwell
Copy link
Member

taylorotwell commented Feb 3, 2017

Can you provide before and after benchmarks? I typically do not accept "performance" PRs without them.

@fernandobandeira
Copy link
Contributor Author

fernandobandeira commented Feb 3, 2017

Running the benchmark on PHP7.0

Code that was executed:

User.php

protected function getAttributeFromArray($key)
    {
        global $BENCHMARK_1;
        if (! empty($BENCHMARK_1)) {
            if (isset($this->attributes[$key])) {
                return $this->attributes[$key];
            }
        } else {
            if (array_key_exists($key, $this->attributes)) {
                return $this->attributes[$key];
            }
        }
    }

benchmark.php
        global $BENCHMARK_1, $BENCHMARK_2;
        $nb = 1000;
        $user = \App\User::first();        
        $t1 = microtime(true);
        $BENCHMARK_1 = false;
        $BENCHMARK_2 = false;
        for ($i = $nb; $i--; ) {
            $user->id;
        }
        $t2 = microtime(true);
        $BENCHMARK_1 = true;
        $BENCHMARK_2 = true;
        for ($i = $nb; $i--; ) {
            $user->id;
        }
        $t3 = microtime(true);
        echo $t2 - $t1;
        echo PHP_SAPI == 'cli' ? "\n" : '<br>';
        echo $t3 - $t2;
        echo PHP_SAPI == 'cli' ? "\n\n" : '<br><br>';
        echo $t2 - $t1 == 0 ? 'N/A' : ($t3 - $t2) * 100 / ($t2 - $t1);
        exit;

Results:
0.033835172653198
0.032655954360962

96.514815206285 Around 3.5%.

@taylorotwell taylorotwell merged commit 8b8fd82 into laravel:5.4 Feb 3, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants