$30 off During Our Annual Pro Sale. View Details »

Writing Faster PHP with HHVM and Hack

Davey Shafik
September 13, 2014

Writing Faster PHP with HHVM and Hack

HHVM is the new hotness, a super-fast alternative PHP runtime from Facebook it can take your existing PHP code base and run it at blazing fast speeds... but is there more?

HHVM also brings Hack to the table which some say is a better PHP. Hack adds numerous features to the PHP language we all know and love that help speed up both development time and runtime performance.

Get the most out of your human and technical resources by using HHVM and Hack today!

Davey Shafik

September 13, 2014
Tweet

More Decks by Davey Shafik

Other Decks in Programming

Transcript

  1. Writing Faster PHP with
    HHVM and Hack

    View Slide

  2. Proprietary and Confidential
    •Community Engineer at Engine
    Yard
    •Author of Zend PHP 5
    Certification Study Guide,
    Sitepoints PHP Anthology: 101
    Essential Tips, Tricks & Hacks &
    PHP Master: Write Cutting Edge
    Code
    •A contributor to Zend Framework
    1 & 2, phpdoc, & PHP internals
    • Original creator of PHAR/
    PHP_Archive
    • Lead for PHPWomen US
    •@dshafik
    Davey Shafik

    View Slide

  3. Let’s start a conversation about
    mental health in tech
    prompt.engineyard.com

    View Slide

  4. About These Slides

    View Slide

  5. Proprietary and Confidential
    Two slides per “slide”!
    Title Slide (for when I’m talking)!
    Details slide (for later)!
    Nobody likes it when you can read the slide just as well as the speaker
    can!
    I like slides that are useful
    About These Slides

    View Slide

  6. A Brief History of HipHop VM
    Better known as HHVM

    View Slide

  7. HPHPc
    2009 - 2012

    View Slide

  8. Proprietary and Confidential
    • Cross-compiler: PHP -> C++!
    • Needed to compile for every change, which took hours!
    • Created huge binaries (approaching 2GB Linux “limit”)!
    • PHP 5.2 (ish) feature-set!
    • Missing support for large parts of the language (e.g. all 5.3+ features
    including namespaces, closures, and dynamic features like
    create_function(), and eval())!
    • Broke the developer workflow
    HPHPc — 2009 - 2012

    View Slide

  9. HipHop VM (HHVM)
    2013 -

    View Slide

  10. Proprietary and Confidential
    • Alternate interpreted runtime with JIT compiler!
    • No compiling process!
    • Twice as fast as PHP in interpreted mode.!
    • Ludicrous speed for JITed code!
    • Bug-for-bug compatible with PHP!
    • Almost up-to 5.6 feature set (e.g. support for variadics, splat)
    HHVM

    View Slide

  11. Hack
    A super-set of PHP

    View Slide

  12. Proprietary and Confidential
    • AKA Hacklang (because “Hack” is un-google-able)!
    • A syntactic super-set of PHP that allows for strong typing via static
    analysis. Adds support for:!
    • type hinting!
    • generics!
    • async functions!
    • annotations!
    • more…!
    • A language sub-set of PHP that disallows a number of bad practices !
    • variable-variables!
    • globals!
    • mixing HTML & PHP!
    • more…
    Hack

    View Slide

  13. Performance

    View Slide

  14. Proprietary and Confidential
    0
    75
    150
    225
    300
    Wordpress 3.9
    SugarCRM CE 6.5.16 - login page
    Drupal 7.28 homepage
    Symfony 2.5 ACME app home page
    ZF 2.3.1 Skeleton App
    Magento 1.9 Homepage
    Magento 1.9 item page
    PHP 5.4 (no OPcache) PHP 5.5 PHP 5.6 hhvm 3.1 (prebuilt binaries) hhvm 3.2-dev(src) PHPNG
    Source: Zeev Suraski http://zsuraski.blogspot.com/2014/07/benchmarking-phpng.html

    View Slide

  15. Agenda
    • Facebook (#2)!
    • Baidu (#5, #1 Search Engine in China)!
    • Wikimedia (incl. Wikipedia, #6)!
    !
    That’s 3 of the top 4 PHP sites in the world, and ~1/3 of the top 10
    overall. (Yahoo! is the outlier, FYI)
    Actual Users

    View Slide

  16. Repo Authoritative Mode
    Ludicrous Speed!

    View Slide

  17. Proprietary and Confidential
    • When code “never” changes (e.g. production)!
    • Extra 20-25% performance increase (similar to apc.stat = 0)!
    • Spends extra time on caching/JITing for maximum performance
    Repo Authoritative Mode

    View Slide

  18. HHVM Setup

    View Slide

  19. Proprietary and Confidential
    login.php
    HHVM Setup
    Nginx php-fpm mysql,pgsql,mongo,

    gearman,redis, etc.
    index.php

    View Slide

  20. Proprietary and Confidential
    login.php
    HHVM Setup
    Nginx mysql,pgsql,mongo,

    gearman,redis, etc.
    index.php
    HHVM

    View Slide

  21. Proprietary and Confidential
    server {
    server_name _;
    root /var/www;
    index index.php;
    location ~ \.php$ {
    fastcgi_pass unix:/var/run/hhvm.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
    include fastcgi_param;
    }
    }
    HHVM Setup

    View Slide

  22. Proprietary and Confidential
    hhvm.server.file_socket = /var/run/hhvm.sock
    hhvm.server.type = fastcgi
    hhvm.server.source_root = /var/www
    hhvm.log.level = Error
    hhvm.log.user_log_file = true
    hhvm.log.file = /var/log/hhvm-error.log
    hhvm.log.access.0.file = /var/log/hhvm-access.log
    hhvm.log.access.0.format=%h %l %u %t \"%r\" %>s %b
    HHVM Setup
    $ hhvm -m daemon -c /etc/hhvm/hhvm.ini -u www-data

    View Slide

  23. Long Term Support

    View Slide

  24. Proprietary and Confidential
    Long Term Support
    Version name Intended release date LTS? End of support
    3.3 11 Sep 2014 yes 13 Aug 2015
    3.4 6 Nov 2014
    3.5 1 Jan 2015
    3.6 26 Feb 2015 yes 28 Jan 2016
    3.7 23 Apr 2015
    3.8 18 Jun 2015
    3.9 13 Aug 2015 yes 14 Jul 2016
    3.10 8 Oct 2015
    3.11 3 Dec 2015
    3.12 28 Jan 2016 yes 29 Dec 2016
    3.13 24 Mar 2016
    3.14* 19 May 2016
    3.15* 14 Jul 2016 yes 15 Jun 2017

    View Slide

  25. Hack
    A better PHP

    View Slide

  26. Proprietary and Confidential
    • Not a new language!
    • Runs through the same HHVM runtime!
    • Strongly typed… but thrown away at run time (type erasure)!
    • Super-fast static analysis!
    • Strict typing informs the runtime to enable better performance
    Hack
    A primary goal of hack is to not
    [negatively] impact the developers
    workflow — especially the REPL;
    whereby we can edit code and refresh our
    browser to immediately see changes.


    - Davey Shafik

    View Slide

  27. Editor Support
    Supports any editor (so long it’s vim or emacs)

    View Slide

  28. File Semantics

    View Slide

  29. Proprietary and Confidential
    • To promote best practices, you cannot mix Hack with HTML (or other
    non-code text)!
    • All hack files must start with • There is no closing tag for hack files!
    • Hack also has multiple modes!
    • XHTML can be embedded using XHP, which makes XHTML tags into
    language constructs
    File Semantics

    View Slide

  30. Hack Modes

    View Slide

  31. Partial Mode

    View Slide

  32. Proprietary and Confidential
    • Default!
    • Gradual Typing!
    • Types are strictly adhered to however:!
    • Not everything must be typed!
    • May call into regular PHP code without error
    Partial Mode
    // Code goes here

    View Slide

  33. Strict Mode

    View Slide

  34. Proprietary and Confidential
    • All code must be typed!
    • Cannot call into non-Hack code!
    • No top-level code!
    • This means your codebase cannot be 100% strict!
    • Arrays must be type hinted!
    • Collections (Vector, Set, Map, Tuple) are preferred
    Strict Mode
    // Code goes here

    View Slide

  35. Declarations Mode
    AKA Decl

    View Slide

  36. Proprietary and Confidential
    • Type hints are trusted but not required
    Declarations Mode
    // Code goes here

    View Slide

  37. Ignoring Errors

    View Slide

  38. Proprietary and Confidential
    • You can ignore errors by marking code as UNSAFE!
    • Applied from the comment to the end of the current block: typically the
    next curly brace “}”!
    • Should be the last resort!
    • May result in run-time errors due to the lack of validation
    Ignoring Errors
    // UNSAFE

    View Slide

  39. Type Hints

    View Slide

  40. Proprietary and Confidential
    • Method Arguments!
    • Return Values!
    • Class Properties
    Type Hints

    View Slide

  41. Proprietary and Confidential
    Types
    Type
    bool Boolean true/false
    Type Name
    int Integer numbers
    float Floating Point numbers
    string Strings
    array Arrays (that can be typed)
    resource Resources (e.g. file streams)
    Class/Interface Name An object type-hint

    View Slide

  42. Proprietary and Confidential
    Types (Cont.)
    Type Name
    mixed Any (not recommended)
    Vector Numerical contiguously indexed Arrays
    Map A typed (both keys and values) associative
    array
    Set An unindexed collection of typed unique
    values
    Tuple A fixed size set of typed values
    Pair A fixed size set of typed values restricted to
    two values, indexed as 0 and 1.

    View Slide

  43. Proprietary and Confidential
    • void — for functions with no return value!
    • this — always refers to $this
    Special Types

    View Slide

  44. Nullable Types

    View Slide

  45. Proprietary and Confidential
    • Allows for nulls to be passed in addition to the specified type!
    • Prefix the type with a ?!
    • e.g. ?int or ?\DateTime.
    Nullable Types
    class DBAdapter {
    public function connect(?string $dsn): ?\PDO
    {
    // $dsn may be null
    // may return an instance of \PDO or null on error
    }
    }

    View Slide

  46. Soft Types

    View Slide

  47. Proprietary and Confidential
    • You can denote the a type-failure should not error by using soft types.!
    • This is great for migrating codebases!
    • To do this precede the type with an @!
    • e.g. @int or @\DateTime.
    Soft Types
    class Calculator {
    public function add(@int $a, @int $b): @int
    {
    // Both $a and $b may not be ints
    // May not return an int
    }
    }
    $calc = new Calculator();
    $calc->add("1", "2");

    View Slide

  48. Custom Types

    View Slide

  49. Proprietary and Confidential
    • Type Aliases (type)!
    • Opaque Types (newtype)!
    • Only used for static analysis.
    Custom Types

    View Slide

  50. Proprietary and Confidential
    type HTTPStatusCode = int;
    !
    class HTTPStatus {
    const HTTPStatusCode OK = 200;
    const HTTPStatusCode FOUND = 302;
    const HTTPStatusCode NOT_FOUND = 404;
    !
    protected Map $status = Map {
    self::OK => "200 OK",
    self::FOUND => "302 Found",
    self::NOT_FOUND => "404 Not Found",
    };
    !
    public function send(HTTPStatusCode $code): bool
    {
    if (isset($this->status[$code])) {
    header('HTTP/1.1 ' .$this->status[$code]);
    return true;
    }
    !
    return false;
    }
    }

    View Slide

  51. Proprietary and Confidential
    function notFound() {
    $status = new HTTPStatus();
    $status->send(404);
    }

    View Slide

  52. Proprietary and Confidential
    • Allows you to give more appropriate names to existing types!
    • e.g. unixtime for int
    Type Aliases

    View Slide

  53. Proprietary and Confidential
    • Opaque types hide their underlying implementation outside of the file in
    which the type is defined.!
    • This means they become immutable except when calling called defined in
    that file!
    • This restriction is not enforced at runtime
    Opaque Types

    View Slide

  54. Proprietary and Confidential
    newtype HTTPStatusCode = int;

    View Slide

  55. Proprietary and Confidential
    function notFound() {
    $status = new HTTPStatus();
    $status->send(HTTPStatus::NOT_FOUND);
    }

    View Slide

  56. Constructor Argument Promotion

    View Slide

  57. Proprietary and Confidential
    • Automatically create properties from constructor arguments!
    • Just precede the argument with a visibility keyword: public, private,
    protected
    Constructor Argument Promotion
    class Adder {
    public function __construct(private int $left, private int $right): void { }
    public function get(): int {
    return $this->left + $this->right;
    }
    }
    $adder = new Adder(1, 3);
    $result = $adder->get(); // 4

    View Slide

  58. Collections

    View Slide

  59. Proprietary and Confidential
    • Arrays — must be typed in strict mode!
    • Tuples — typed arrays!
    • Pairs — can only contain 2 pieces of data!
    • Vectors — numerically, consecutively keyed only!
    • Maps — ordered dictionaries that allow int or string keys!
    • Sets — unordered collection of unique values!
    !
    • Immutable variants
    Collections

    View Slide

  60. Arrays

    View Slide

  61. Proprietary and Confidential
    • array — Untyped (only allowed in partial mode)!
    • array<[type]> — [type] typed values, with integer keys!
    • array<[type1], [type2]> — [type1] typed keys, with [type2]
    typed values.
    Arrays
    function createArray(): array {
    return array(1, 2, 3);
    }

    View Slide

  62. Tuples

    View Slide

  63. Proprietary and Confidential
    • Internally identical to arrays!
    • Fixed size!
    • Implicitly Type hinted by the values used to define it or!
    • Explicitly Type hinted using the literal syntax
    Tuples
    function createTuple(): void {
    $foo = tuple(1, 2, "3");
    // Do more with the tuple
    }
    function createTuple(): (int, int, string) {
    return tuple(1, 2, "3");
    }

    View Slide

  64. Pairs

    View Slide

  65. Proprietary and Confidential
    • Can contain only two values, keyed as 0 and 1!
    • Immutable
    Pairs
    function getTask(): Pair {
    return Pair { "C039D17D", "checkPing" };
    }

    View Slide

  66. Vectors

    View Slide

  67. Proprietary and Confidential
    • Vectors can only use integer keys
    Vectors
    function getCommunityEngineers(): Vector {
    return Vector {"Davey", "PJ", "You?"};
    }

    View Slide

  68. Maps

    View Slide

  69. Proprietary and Confidential
    • Maps are an ordered dictionary, which can have integer or string keys.!
    • Must specify both key and values types when type hinting.
    Maps
    function getTags(): Map {
    return Map {"php" => "PHP", "hack" => "Hack"};
    }

    View Slide

  70. Sets

    View Slide

  71. Proprietary and Confidential
    • Unordered Collection with no keys!
    • Unique values
    function getTags(): Set {
    return Set { "php", "hack", "hhvm" };
    }

    View Slide

  72. Immutability

    View Slide

  73. Proprietary and Confidential
    • Simply prefix the class name with Imm
    Immutability
    function getTags(): ImmMap {
    $map = ImmMap {"php" => "PHP", "hack" => "Hack"};
    $map["hhvm"] = "HHVM";
    }
    |13 col 6 error| You cannot mutate this
    |12 col 13 error| This is an object of type ImmMap

    View Slide

  74. Appending Elements

    View Slide

  75. Proprietary and Confidential
    • Only Vectors allow $foo[] = "bar" syntax!
    • Pairs and Tuples do not allow additional elements!
    • Maps allow appending of Pairs. First value is key, second value is value
    Appending Elements
    function appendToMap(): void {
    $m = Map { 0 => "foo", 1 => "bar" };
    $m[] = Pair { 5, "bat" };
    var_dump($m);
    }

    View Slide

  76. Object Oriented Interface

    View Slide

  77. Proprietary and Confidential
    • Based on the SPL!
    • Allows adding/removing/manipulation methods!
    • Allows you to use them as objects, rather than just “better” arrays
    Object Oriented Interface

    View Slide

  78. Breaking Iteration

    View Slide

  79. Proprietary and Confidential
    • Because collections are objects, you cannot modify them during
    iteration.
    Breaking Iteration
    Fatal error: Uncaught exception
    'InvalidOperationException' with message
    'Collection was modified during iteration' in

    View Slide

  80. Shapes

    View Slide

  81. Proprietary and Confidential
    • Tuples with a pre-defined structure!
    • Can be used as a form of validation!
    • Ensures integrity
    Shapes
    newtype HTTPRequest = shape(
    'status' => HTTPStatusCode,
    'headers' => Map,
    'data' => shape (
    'GET' => ?Map,
    'POST' => ?Map,
    'COOKIE' => ?Map,
    'SERVER' => Map
    ),
    'body' => ?string
    );

    View Slide

  82. Anonymous Functions

    View Slide

  83. Proprietary and Confidential
    • Like closures but they inherit parent scope!
    • Much more concise!
    !
    • Multiple Expressions
    Anonymous Functions
    $fn = $args ==> expression;
    $fn = ($arg1, $arg2) ==> { expression; return ...; };
    $list = ;
    array_walk($items, $item ==> $list->appendChild({$item});
    !
    echo $list;

    View Slide

  84. XHP — XML Fragments as Expressions

    View Slide

  85. Proprietary and Confidential
    • Makes XML syntax a top-level syntax!
    • No longer strings!
    • Auto-escapes for security!
    • Allows for OO semantics, for composable widgets, for tempting!
    • Must be XML, e.g.

    XHP — XML Fragments as Expression
    echo Hello World;

    View Slide

  86. Proprietary and Confidential
    • Classes are defined by prefixing the class name with a colon!
    • Classes extend the :x:element base class which has DOM-like
    methods:!
    • appendChild()
    • prependChild()
    • replaceChildren()
    • getChildren()
    • getFirstChild()
    • getLastChild()
    • getAttribute(), getAttributes()
    • setAttribute(), setAttributes()
    • isAttributeSet()
    • removeAttribute()
    XHP (Cont.)

    View Slide

  87. Proprietary and Confidential
    The PHP Way
    echo '';
    foreach ($items as $item) {
    echo '';
    echo htmlentities($item, ENT_QUOTES, 'UTF-8');
    echo '';
    }
    echo '';
    ?>

    View Slide

  88. Proprietary and Confidential
    The Hack Way
    $list = ;
    foreach ($items as $item) {
    $list->appendChild({$item});
    }

    View Slide

  89. Proprietary and Confidential
    Feedback & Questions: !

    Twitter: @dshafik
    Email: [email protected]
    Slides: http://daveyshafik.com/slides

    View Slide

  90. Proprietary and Confidential
    • Hack Lang: http://hacklang.org!
    • HHVM: http://hhvm.com!
    • Building a Better PHP: https://blog.engineyard.com/2014/hhvm-hack
    (Engine Yard Blog)
    Resources
    http://ey.io/hhvm-hack

    View Slide