神刀安全网

Computing Pi with Peachpie

We have been working hard to produce something tangible and/or executable to demonstrate some of the usecases, features, and benefits of Peachpie. In honor of Pi Day last week, it seemed like a good idea to produce the first demo of the PHP compiler to .NET by allowing it to compute Pi. 

Peachpie Leibniz Demo

First and foremost, we would like to emphasize that Peachpie is still in its absolute infancy and the development is currently in the early stages. However, we felt that in order to get the message across, we invariably needed to show something tangible. Therefore, we taught Peachpie to compute simple algebraic operations, and we demonstrated it via the calculation of Pi. 

Test Configuration

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

Test Source Code

The method used was the Leibniz formula for π. Please refer to  this article to see how this formula works. Please be aware that this method is strictly designed for demonstration purposes and is by no means suitable for a precise computation of Pi.

Image 1: Test Source Code

Test Results

The test results indicate that Peachpie outperforms both tested versions of PHP as well as Phalanger by a significant distance. The speed of computation (approximately 11.5 seconds) of Phalanger was comparable to that of PHP 7.0.4 on a x86 processor, while Peachpie calculated the same 100,000,000-step accuracy in just over 2 seconds, as shown by the following table:  

Computing Pi with Peachpie

Table 1: Test Results

Computing Pi with Peachpie

Image 2: Test Results

This performance discrepancy is thanks to Peachpie’s type analysis and C#-like emitted code, subsequent .NET JIT optimizations, and the compilation to actual CPU machine code.

Interestingly, both Peachpie and Phalanger were able to calculate a more precise result than the pure PHP versions. Finally, they both run on x32, x64, and any other CPU supported by .NET. It is important to stress that Peachpie is still a work in progress and numerous optimizations can still be made, which will presumably increase the speed even further.

Other Considerations

Aside from the aforementioned performance benefits, there are additional advantages associated with the use of a compiler within Microsoft Visual Studio. Firstly, this popular IDE produces some incredibly useful and user-friendly statistics, as the following examples indicate:

Peachpie:

Computing Pi with Peachpie


Image 3: Peachpie Visual Studio Diagnostic Tools

Phalanger:

Computing Pi with Peachpie

Image 4: Phalanger Visual Studio Diagnostic Tools

Furthermore, if we compare Phalanger with Peachpie, we can clearly note how Phalanger stresses the garbage collector, while Peachpie’s improved architecture represents an insignificant burden for the GC, keeping the memory consumption at a minimum.

Intermediate Code Comparison

For completion sake, we have also included the comparison of the PHP 5.6 OpCode, the MSIL output produced by Peachpie, as well as the decompiled C# from the Peachpie MSIL, and finally the Phalanger-produced MSIL decompiled into C#:

PHP 5.6 OpCode:

We obtained this code using the Vulcan Logic Disassembler:

function name:  leibniz_pi number of ops:  39 compiled vars:  !0 = $pi, !1 = $top, !2 = $bot, !3 = $minus, !4 = $i line     # *  op                           fetch          ext  return  operands ---------------------------------------------------------------------------------    5     0  >   EXT_NOP    7     1      EXT_STMT          2      ASSIGN                                                   !0, 4          3      EXT_STMT          4      ASSIGN                                                   !1, 4          5      EXT_STMT          6      ASSIGN                                                   !2, 3          7      EXT_STMT          8      ASSIGN                                                   !3, true    9     9      EXT_STMT         10      ASSIGN                                                   !4, 0         11  >   IS_SMALLER                                       ~5      !4, 100000000         12      EXT_STMT         13    > JMPZNZ                                       11          ~5, ->35         14  >   POST_INC                                         ~6      !4         15      FREE                                                     ~6         16    > JMP                                                      ->11   11    17  >   EXT_STMT         18    > JMPZ                                                     !3, ->23         19  >   DIV                                              ~7      !1, !2         20      SUB                                              ~8      0, ~7         21      QM_ASSIGN                                        ~9      ~8         22    > JMP                                                      ->25         23  >   DIV                                              ~10     !1, !2         24      QM_ASSIGN                                        ~9      ~10         25  >   ASSIGN_ADD                                    0          !0, ~9   12    26      EXT_STMT         27    > JMPZ                                                     !3, ->30         28  >   QM_ASSIGN                                        ~12     false         29    > JMP                                                      ->31         30  >   QM_ASSIGN                                        ~12     true         31  >   ASSIGN                                                   !3, ~12   13    32      EXT_STMT         33      ASSIGN_ADD                                    0          !2, 2   14    34    > JMP                                                      ->14   16    35  >   EXT_STMT         36    > RETURN                                                   !0   17    37*     EXT_STMT         38*   > RETURN                                                   null  branch: #  0; line:     5-    9; sop:     0; eop:    10; out1:  11 branch: # 11; line:     9-    9; sop:    11; eop:    13; out1:  35; out2:  17 branch: # 14; line:     9-    9; sop:    14; eop:    16; out1:  11 branch: # 17; line:    11-   11; sop:    17; eop:    18; out1:  19; out2:  23 branch: # 19; line:    11-   11; sop:    19; eop:    22; out1:  25 branch: # 23; line:    11-   11; sop:    23; eop:    24; out1:  25 branch: # 25; line:    11-   12; sop:    25; eop:    27; out1:  28; out2:  30 branch: # 28; line:    12-   12; sop:    28; eop:    29; out1:  31 branch: # 30; line:    12-   12; sop:    30; eop:    30; out1:  31 branch: # 31; line:    12-   14; sop:    31; eop:    34; out1:  14 branch: # 35; line:    16-   17; sop:    35; eop:    38 path #1: 0, 11, 35, path #2: 0, 11, 17, 19, 25, 28, 31, 14, 11, 35, path #3: 0, 11, 17, 19, 25, 30, 31, 14, 11, 35, path #4: 0, 11, 17, 23, 25, 28, 31, 14, 11, 35, path #5: 0, 11, 17, 23, 25, 30, 31, 14, 11, 35, End of function leibniz_pi.

Image 5: PHP 5.6 OpCode

Peachpie-poduced MSIL:

.method public static      float64 leibniz_pi (         class [pchpcor]Pchp.Core.Context '<ctx>'     ) cil managed  {     // Method begins at RVA 0x2054     // Code size 102 (0x66)     .maxstack 3     .locals init (         [0] float64,         [1] float64,         [2] float64,         [3] bool,         [4] int64,         [5] valuetype [pchpcor]Pchp.Core.PhpNumber     )      IL_0000: ldc.r8 4     IL_0009: stloc.0     IL_000a: ldc.r8 4     IL_0013: stloc.1     IL_0014: ldc.r8 3     IL_001d: stloc.2     IL_001e: ldc.i4.1     IL_001f: stloc.3     IL_0020: ldc.i4.0     IL_0021: conv.i8     IL_0022: stloc.s 4      IL_0024: br.s IL_0058     // loop start (head: IL_0058)         IL_0026: ldloc.0         IL_0027: ldloc.3         IL_0028: brtrue.s IL_002f          IL_002a: ldloc.1         IL_002b: ldloc.2         IL_002c: div         IL_002d: br.s IL_0033          IL_002f: ldloc.1         IL_0030: ldloc.2         IL_0031: div         IL_0032: neg          IL_0033: add         IL_0034: stloc.0         IL_0035: ldloc.3         IL_0036: brtrue.s IL_003b          IL_0038: ldc.i4.1         IL_0039: br.s IL_003c          IL_003b: ldc.i4.0          IL_003c: stloc.3         IL_003d: ldloc.2         IL_003e: ldc.i4.2         IL_003f: conv.r8         IL_0040: add         IL_0041: stloc.2         IL_0042: ldloc.s 4         IL_0044: ldc.i4.1         IL_0045: conv.i8         IL_0046: call valuetype [pchpcor]Pchp.Core.PhpNumber [pchpcor]Pchp.Core.PhpNumber::Add(int64, int64)         IL_004b: stloc.s 5         IL_004d: ldloca.s 5         IL_004f: call instance int64 [pchpcor]Pchp.Core.PhpNumber::ToLong()         IL_0054: stloc.s 4         IL_0056: br.s IL_0024          IL_0058: ldloc.s 4         IL_005a: ldc.i4 100000000         IL_005f: conv.i8         IL_0060: clt         IL_0062: brtrue.s IL_0026     // end loop      IL_0064: ldloc.0     IL_0065: ret } // end of method PhpNumberTest::leibniz_pi

Image 6: Peachpie-produced MSIL

Decompiled C# from Peachpie MSIL:

public static double leibniz_pi(Context <ctx>)  {      double num = 4.0;      double num2 = 4.0;      double num3 = 3.0;      bool flag = true;      for (long num4 = 0L; num4 < 100000000L; num4 = PhpNumber.Add(num4, 1L).ToLong())      {          num += (flag ? (-(num2 / num3)) : (num2 / num3));          flag = !flag;          num3 += (double)2;      }      return num;  }

Image 7: Decompiled C# from Peachpie MSIL

Phalanger-produced MSIL decompiled to C#:

public static object leibniz_pi(ScriptContext <context>)  {      object obj = 4.0;      object obj2 = 4.0;      object obj3 = 3.0;      object obj4 = true;      object obj5 = 0;      while (PhpComparer.CompareOp(obj5, 100000000, false) < 0)      {          object obj6 = (!Convert.ObjectToBoolean(obj4)) ? Operators.Divide(obj2, obj3) : Operators.Minus(Operators.Divide(obj2, obj3));          obj = Operators.Add(obj, obj6);          obj4 = ((!Convert.ObjectToBoolean(obj4)) ? true : false);          int num = 2;          obj3 = Operators.Add(obj3, num);          obj5 = Convert.ObjectToInteger(Operators.Add(obj5, 1));      }      return obj;  }

Image 8: Decompiled C# from Phalanger MSIL

For more information, visitpeachpie.io, our Github repo , or follow us on Twitter @pchpcompiler or on Facebook.

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Computing Pi with Peachpie

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮