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

Performance testing: Bind static variables as non-references. #18

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

TysonAndre
Copy link
Owner

@TysonAndre TysonAndre commented Sep 26, 2021

The goal is to see if this is worth doing in opcache.
This creates a static variable that is a value instead of a reference,
subsequent assignments such as $x = null; do not modify the original
declaration.
(If $x was previously a reference before the static var statement,
it continues to be unset before the
expression on the right hand side is assigned to $x)

(e.g. static $x : = [new ArrayObject(['foo' => 'bar'])]

  1. Locally benchmark until implementing changes so that opcache can
    infer when it is safe to bind a static $var with $var as a
    non-reference
    (e.g. only used by value, no foreach by ref, no $$ variable
    access or functions such as extract, no require*/include* statements,
    not in the top-level file scope, etc.).

    For example, function (): SomeClass { static $var = new SomeClass(); return $var; }
    is likely much less efficient as a non-reference rather than a static variable
    but opcache doesn't attempt to optimize it.

    In php 8.1, the workaround of using private const SOME_METHOD_LOCAL_OBJ = new SomeClass(); exists but initialization later than that may be useful, e.g. if initializing SomeClass or its dependencies is slow.

  2. Work out how to make the opcache changes correctly and safely

  3. Being able to do this automatically may result in more efficient code, especially with the opcache JIT compiler

<?php
const V1 = new stdClass();

function example1() {
    static $x := ['value' => V1];
    return $x;
}
function example2() {
    static $x = ['value' => V1];
    return $x;
}

function main() {
    $count = 50_000_000;
    $t1 = hrtime(true)/1_000_000_000;
    for ($i = 0; $i < $count; $i++) { example1(); }
    $t2 = hrtime(true)/1_000_000_000;
    for ($i = 0; $i < $count; $i++) { example2(); }
    $t3 = hrtime(true)/1_000_000_000;

    printf("Time for %d iterations:\nexample1 %.6f\nexample2 %.6f\n", $count, $t2-$t1, $t3-$t2);
}
main();

This benchmark was around 3% faster, for example.

The goal is to see if this is worth doing in opcache.
This creates a static variable that is a value instead of a reference,
subsequent assignments such as `$x = null;` do not modify the original
declaration.
(If $x was previously a reference before the `static` var statement,
it continues to be unset before the
expression on the right hand side is assigned to $x)

(e.g. `static $x : = [new ArrayObject(['foo' => 'bar'])]`

1. Locally benchmark **until implementing changes so that opcache can
   infer when it is safe to bind a `static $var` with $var as a
   non-reference** (e.g. only used by value, no foreach by ref, no $$ variable
   access or functions such as extract, no `require*/include*` statements,
   not in the top-level file scope, etc.).

   For example, `function (): int { static $var = 2; return $var; }`
   is likely much less efficient than a local variable
   but opcache doesn't attempt to optimize it.
2. Work out how to make the opcache changes correctly and safely
@TysonAndre
Copy link
Owner Author

static const LOCAL_TO_THIS_STATEMENT_LIST_SCOPE = new Something(); - #10 in some form may be a better approach to a new static variable syntax.

It may be confusing having a different static that can't have the original get modified, but can have the copied get modified, so the use case is less compelling

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.

1 participant