Peachpie’s Debut: Running PHP in .NET

Last week we taught Peachpie to compute simple arithmetic operations and demonstrated this ability on the Leibniz formula for Pi. We published a first microbenchmark, where we compared how quickly the irrational number was calculated with Peachpie compared to PHP 5.6 and 7, as well as with Phalanger. The results for this particular benchmark were surprisingly favorable for Peachpie. Since then, we have worked hard on the option of producing an executable file and we finally managed to achieve this feat.

Apprentice Beats the Master

In the Pi calculation, we not only tested how Peachpie compares to PHP 5.6 and 7, but also to its predecessor, Phalanger. The results indicated that Phalanger performed similarly to PHP 7, while Peachpie was able to compute Pi approximately six times faster. Peachpie’s dominant performance, albeit of course this particular operation was optimized as much as possible, made us look into the differences with Phalanger in more detail. While we do call Peachpie the successor to Phalanger, the reality is that its architecture is radically different and – we hope – vastly superior. A closer look at the performance of the two compilers over a wide range of computational steps reveals how large the discrepancy really is:

Phalanger versus Peachpie (less is better):

Performance of Peachpie versus Phalanger

The diagram above depicts the performance of Peachpie against Phalanger when calculating Pi and in the quicksort alogorithm.

Building Peachpie

Here is a quick introductory video on how Peachpie works:

The complete project can be found in its entirety on our GitHub repository. Simply open Peachpie.sln in Visual Studio and build. This will produce the compiler command line utility – peach.exe:

Building Peachpie

Using Peachpie Command Line Utility

Peachpie currently only supports a small subset of the PHP language. The command line utility produces a command line EXE or portable DLL, which can then be used in your C# project as a reference. There is no help yet; the currently supported peach.exe arguments are:

[shell]
pchp.exe [/r:AssemblyName] [/t:exe|library] [/nologo] [/out:OutputFile] [/main:EntryPoint] file1.php file2.php …
[/shell]

A sample use would be to write the command:

[shell]
pchp /target:exe test.php
[/shell]

This will create the command line executable program, which in turn will start executing global code in first script provided – test.php.

Sample Program

Below you can find the first sample program, the Leibniz formula for Pi, which we used in last week’s blog microbenchmarking blog post:

[php]
[test.php]
<?php

echo "Computing Pi … :", leibniz_pi(10000);

class PhpNumberTest
{
/**
* @param int $steps
*/
static function leibniz_pi($steps)
{
return leibniz_pi($steps);
}
}

/**
* @param int $steps
*/
function leibniz_pi($steps)
{
$pi = 4.0; $top = 4.0; $bot = 3.0; $minus = TRUE;

for ($step = 0; $step < $steps; $step ++)
{
$pi += ( $minus ? -($top/$bot) : ($top/$bot) );
$minus = ( $minus ? FALSE : TRUE);
$bot += 2;
}

return $pi;
}
[/php]

This process will produce a test.exe application. Please note that in case of any unsupported behavior, Peachpie will crash unconditionally. It is still in the concept phase and by no means a finished product yet. Many features and behaviors are not yet supported, but will be as we continue to progress in our work in the compiler.

Here are some of the things that Peachpie is already capable of doing:

  • Compiling global functions
  • Compiling class functions (no overloading yet)
  • PHPDoc above functions. As of now, this is used for defining parameter types, even combinations like int|double.
  • Loops, goto statements, if statements
  • Local variables, assignments, number comparison, numeric operators
  • Converting between number, boolean, long and double
  • Echo of string, number and boolean
  • Returning a value from a function
  • Type analysis on numbers
  • Working natively with 64 bit integers (long)
  • Calling global PHP functions

Sneak Peek: Using C# to Call PHP

What is more interesting, using the /t:library argument, we can create a dynamically linked library file (dll), which can be referenced by a C# (or any other .NET) project. In other words, we have already managed to achieve one-way interoperability, enabling the calling of PHP from C#.

We used the sample pchp /t:library test.php. We can then check the resulting test.dll in ILSpy. Below, you can see a screenshot of the code decompiled from compiled PHP to C# in ILSpy:

Decompiled C# Code
Note that the PHP function is strongly typed. It returns a double and gets a long instead of a generic value.

You can then create a C# project and add test.dll and phpcor.dll as references, as depicted below:

Adding test.dll and phpcor.dll to your C# project in Visual Studio

Quick explanation:

Context.CreateConsole() is a Peachpie runtime object, representing a PHP runtime thread. This will be used heavily in the future and allows for hardcore .NET interoperability options. Furthermore, it enables for the simulation of PHP runtime in .NET.

In our sample we called the class function instead of a global function. The reason is that C# does not support calling global functions, and Peachpie does not provide an API for this yet.

That was it for the very first demo of Peachpie, the PHP compiler to .NET. Please note that any unsupported behaviors and features will cause the compiler to crash. It is still in the conceptual phase and very much a work in progress.

Posted on March 29, 2016, in category Announcement, Benchmark, Tutorial, tags: , , , , ,