We have been busy adding more and more features to Peachpie and benchmarking them against standard versions of PHP, but we also think it is important to share our thoughts on Microsoft Roslyn, which made Peachpie possible.
Microsoft Roslyn: The Modern Compiler Platform
Back when we were developing Phalanger, there were a few crucial issues that we weren’t able to solve – or at least not very efficiently. Phalanger’s architecture caused certain applications to run relatively slowly and other shortcomings implied that we were not able to compile to .NET as effectively as we had intended. The Roslyn framework did us a huge favor and introduced several features that allow Peachpie and any other Roslyn-enabled compiler to work with dynamic objects with an unprecedented efficiency.
One key differentiator is that while an ordinary compiler discards all of its intermediate information once the final code is output, Roslyn allows those compilers that were built on top of it to access the data from each step via its own APIs. The entire compile-execute process can thus be invoked from within .NET applications in a common way.
By far the main benefit of building a compiler on top of Roslyn is the massive performance improvement. Not only is the compilation speed lightning fast thanks to the parallel processing of the source code, but Roslyn also remembers the intermediate steps from the previous compilation. For example, it remembers already parsed source codes and previously processed reference symbols. The reference symbols used to be a nightmare for Phalanger; they had to be loaded into the AppDomain, which was painfully slow and also meant that they couldn’t be unloaded afterwards. Roslyn, however, loads references merely by parsing the binary metadata from the file header, which is incomparably faster.
Last but not least, Roslyn is a modern compiler with a contemporary architecture. It has been designed from the ground up to fit today’s needs and provide the most effective compilation process.
Roslyn and Dynamic Languages
Particularly for dynamic languages, the recent versions of .NET have brought a few immeasurable benefits. Firstly, it has a built-in mechanism for handling dynamic objects, as we showed in last week’s blog post where we demonstrated the strength of the call sites. While specifically PHP, for instance, constantly has to look up information in hash tables, the call site renders this process obsolete.
As a part of Roslyn, we can find helper classes called ILBuilder and MetadataWriter. In addition to their small footprint and much greater performance in comparison to old .NET ILBuilder, it allows for a more low-level emission of IL. Thanks to their low level features, it makes possible for a more efficient use of the call site objects.
Another massive advantage of .NET is that it essentially offers an interoperability with other dynamic languages, such as IronPython or IronRuby. All objects from all languages that provides the IDynamicMetaObjectProvider will therefore be able to interoperate with each other, which is certainly extremely appealing particularly to PHP developers.
Taking Type Safety in PHP to a Whole New Level
Finally, the new PHP 7 makes a serious attempt at being a strongly typed language. .NET, however, would not only emphasize this objective, but actually produces a more strict and secure code. Thanks to PHP’s PHPDoc comments and newly introduced type hints and return type hints, PHP can take advantage of the .NET type safety, albeit this will be an optional benefit that can easily be turned off. Furthermore, Peachpie provides an incredibly fast compile time check and creates typed interfaces for .NET languages, allowing for a type safe use:
Property Assignment Test
We have created another benchmark to demonstrate the strength of Roslyn’s powered call site – this time using the property assignment. The test configuration remains the same as previously:
- Windows 10 x64
- Lenovo Thinkpad Yoga 260
- Core i7 6500U
- 8GB DDR4 RAM
As the diagram above indicates, Peachpie handled the process in 0.322 seconds, almost 9 times faster than PHP 7 (2.660 sec), while PHP 5.6 took 11.483 seconds for the same task.