神刀安全网

How .NET Handles PHP Static Locals

Moving on down the roadmap, we are implementing more and more PHP functionalities into Peachpie compiler. This week, we would like to introduce a particularly popular one – Static Local Variables.

Static Local Variables in PHP

The benefits of Peachpie compiler for PHP developers are relatively evident. However, we are frequently asked about some of the advantages that Peachpie compiler   can bring to .NET developers, as well. PHP offers a number of unique features that, if used properly, have the ability to make your life a whole lot easier.

Static local variables are a good example of such a feature; when declared in a function scope, such a variable survives past the function’s end and retains its value until the next function invocation. PHP static locals are different to .NET statics, since PHP static variables only live in the frame of the current request, whereas in .NET, they live across all the requests and are not thread safe, for instance.

In fact, you will not find anything exactly equivalent to static locals in .NET, whilst this feature is commonly used and quite popular in PHP.

Compiling Statics From PHP to .NET

Compiling such a construct from PHP to .NET proved to be quite the challenge. Peachpie compiler generates efficient MSIL code that deals with statics, as can be seen in the following example.

PHP:

<?php function initializeMe() {  static $alreadyCalled = false;   if ($alreadyCalled)   return;   $alreadyCalled = true;   echo "Once!"; }

The code above declares the local static variable $alreadyCalled, which is initialized as ‘false’. Subsequently, the code continues as if it were still false, and then changes the value to ‘true’. The next time the function is called, $alreadyCalled contains the value from the previous call and the function call is terminated.

.NET / C#:

private sealed class alreadyCalled<> {     public bool value = false; }  public static void initializeMe(Context <ctx>) {     var alreadyCalled = <ctx>.GetStatic<alreadyCalled<>>();     if (alreadyCalled.value)         return;      alreadyCalled.value = true;     <ctx>.Echo("Once!"); }

Peachpie compiles the code into the C# equivalent above. It generates a class that holds the value of static variable. The logic of this construct is hidden in the implementation of Context, which is a special Peachpie object, representing a single web request. Internally, it remembers the instance of the holder class through generics. If you are interested in the details of this, you can find them  here .

Benchmarking

There are two basic and typical usages of static locals; counting something and checking to ensure that we do not enter into a function more than once:

<?php function counter() {  static $n = 10.0;  $n ++; }  function initializeMe() {  static $alreadyCalled = false;   if ($alreadyCalled) return;  $alreadyCalled = true;   echo "Once!"; }  function test() {  for ($i = 0; $i < 10000000; $i++) {   counter();   initializeMe();  } }

Test Configuration:

  • Windows 10 x64
  • Lenovo Thinkpad Yoga 260
  • Core i7 6500U
  • 8GB DDR4 RAM

Results:

Again, PHP 7 has managed to tweak its performance significantly compared to PHP 5.6.

How .NET Handles PHP Static Locals
Microbenchmarking static local variables in PHP and Peachpie

Peachpie handled the process even more quickly, however, requiring about 0.25 seconds, compared to the 1.68 seconds of PHP 7. PHP 5.6 needed  35.96 seconds, which we had trouble depicting properly in the diagram. 

Stay informed about our progress on our GitHub repo by following us on Twitter or Facebook

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » How .NET Handles PHP Static Locals

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址