What Happens when PHP Static Fields are Compiled to .NET

Read about what happens to PHP static fields when compiled to .NET.

Static Fields

In the context of PHP fields, the meaning of a “static” keyword would differ from the typical C# “static”. In PHP, a static field does not live across the whole process lifetime. Instead, it is valid in the frame of one web request. Additionally, when running multiple web requests concurrently, each of them has its own “static”.

.NET languages like C# do not have constructs to express such types of semantics, therefore our PHP compiler must wrap PHP statics into its own representation.

Every bunch of static fields is represented as a nested class named “_statics”, whose instance is lazily bound to a web request, represented as a Context class in Peachpie. Then, by accessing a static field of a class, the compiler actually generates code that retrieves instances of “_statics” from Context and accesses its instance (non-static) fields.

Sample Code

The sample below depicts a piece of code compiled from PHP to MSIL, decompiled to C# to show how it works and what the user has to write in order to achieve similar behavior.

<?php
class Dog {
 
 /** @var int */
 static $_woofs = 0;
 
 function Woof() {
  Dog::$_woofs ++;
 }
}

This is how the above code is translated to .NET by Peachpie and decompiled back to C#:

public class Dog{

    protected readonly Context <ctx>;

    public sealed class _statics{
        public long _woofs = 0L;
    }

    public virtual PhpValue Woof() {
        this.<ctx>.GetStatic<Dog._statics>()._woofs ++;
        return PhpValue.Null;
    }
}

Benchmarking

Test Configuration

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

Static fields are complicated for the development of Peachpie in two ways. Firstly, it is difficult to express such a construct in .NET semantically correctly. In addition, it is essential to make the resulting code highly performant. In order to benchmark the performance of this construct, we called Woof() in a loop for 10,000,000 times and compared the execution speed with PHP 5.6 and PHP 7. The following diagram illustrates the results of our microbenchmark:

As with many previous benchmarks, the massive improvement of PHP between versions 5.6 and 7 is evident once again. While the loop finished in 16.9472 seconds with PHP 5.6, PHP 7 took 0.5996 seconds. Peachpie handled the operation in 0.1449 seconds, about four times as quickly.

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

Share this article:Share on FacebookShare on VKPin on PinterestShare on Google+Tweet about this on TwitterShare on LinkedInShare on Reddit
Loading Facebook Comments ...

Leave a Reply