Pro Yearly is on sale from $80 to $50! »

Writing Faster PHP with HHVM and Hack

Fee39f0c0ffb29d9ac21607ed188be6b?s=47 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!

Fee39f0c0ffb29d9ac21607ed188be6b?s=128

Davey Shafik

September 13, 2014
Tweet

Transcript

  1. Writing Faster PHP with HHVM and Hack

  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
  3. Let’s start a conversation about mental health in tech prompt.engineyard.com

  4. About These Slides

  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
  6. A Brief History of HipHop VM Better known as HHVM

  7. HPHPc 2009 - 2012

  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
  9. HipHop VM (HHVM) 2013 -

  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
  11. Hack A super-set of PHP

  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
  13. Performance

  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
  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
  16. Repo Authoritative Mode Ludicrous Speed!

  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
  18. HHVM Setup

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

    etc. index.php
  20. Proprietary and Confidential login.php HHVM Setup Nginx mysql,pgsql,mongo,
 gearman,redis, etc.

    index.php HHVM
  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
  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
  23. Long Term Support

  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
  25. Hack A better PHP

  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
  27. Editor Support Supports any editor (so long it’s vim or

    emacs)
  28. File Semantics

  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 <?hh! • 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
  30. Hack Modes

  31. Partial Mode

  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 <?hh // Code goes here
  33. Strict Mode

  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 <?hh // strict // Code goes here
  35. Declarations Mode AKA Decl

  36. Proprietary and Confidential • Type hints are trusted but not

    required Declarations Mode <?hh // decl // Code goes here
  37. Ignoring Errors

  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
  39. Type Hints

  40. Proprietary and Confidential • Method Arguments! • Return Values! •

    Class Properties Type Hints
  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
  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.
  43. Proprietary and Confidential • void — for functions with no

    return value! • this — always refers to $this Special Types
  44. Nullable Types

  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 <?hh
 class DBAdapter { public function connect(?string $dsn): ?\PDO { // $dsn may be null // may return an instance of \PDO or null on error } }
  46. Soft Types

  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 <?hh 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");
  48. Custom Types

  49. Proprietary and Confidential • Type Aliases (type)! • Opaque Types

    (newtype)! • Only used for static analysis. Custom Types
  50. Proprietary and Confidential <?hh // strict type HTTPStatusCode = int;

    ! class HTTPStatus { const HTTPStatusCode OK = 200; const HTTPStatusCode FOUND = 302; const HTTPStatusCode NOT_FOUND = 404; ! protected Map<HTTPStatusCode, string> $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; } }
  51. Proprietary and Confidential <?hh function notFound() { $status = new

    HTTPStatus(); $status->send(404); }
  52. Proprietary and Confidential • Allows you to give more appropriate

    names to existing types! • e.g. unixtime for int Type Aliases
  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
  54. Proprietary and Confidential newtype HTTPStatusCode = int;

  55. Proprietary and Confidential <?hh function notFound() { $status = new

    HTTPStatus(); $status->send(HTTPStatus::NOT_FOUND); }
  56. Constructor Argument Promotion

  57. Proprietary and Confidential • Automatically create properties from constructor arguments!

    • Just precede the argument with a visibility keyword: public, private, protected Constructor Argument Promotion <?hh 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
  58. Collections

  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
  60. Arrays

  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 <?hh // strict function createArray(): array<int> { return array(1, 2, 3); }
  62. Tuples

  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 <?hh
 function createTuple(): void { $foo = tuple(1, 2, "3"); // Do more with the tuple } function createTuple(): (int, int, string) { return tuple(1, 2, "3"); }
  64. Pairs

  65. Proprietary and Confidential • Can contain only two values, keyed

    as 0 and 1! • Immutable Pairs <?hh // strict function getTask(): Pair<string, string> { return Pair { "C039D17D", "checkPing" }; }
  66. Vectors

  67. Proprietary and Confidential • Vectors can only use integer keys

    Vectors <?hh // strict function getCommunityEngineers(): Vector<string> { return Vector {"Davey", "PJ", "You?"}; }
  68. Maps

  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 <?hh // strict function getTags(): Map<string, string> { return Map {"php" => "PHP", "hack" => "Hack"}; }
  70. Sets

  71. Proprietary and Confidential • Unordered Collection with no keys! •

    Unique values <?hh // strict function getTags(): Set<string> { return Set { "php", "hack", "hhvm" }; }
  72. Immutability

  73. Proprietary and Confidential • Simply prefix the class name with

    Imm Immutability <?hh // strict function getTags(): ImmMap<string, string> { $map = ImmMap {"php" => "PHP", "hack" => "Hack"}; $map["hhvm"] = "HHVM"; } <file>|13 col 6 error| You cannot mutate this <file>|12 col 13 error| This is an object of type ImmMap
  74. Appending Elements

  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 <?hh // strict function appendToMap(): void { $m = Map { 0 => "foo", 1 => "bar" }; $m[] = Pair { 5, "bat" }; var_dump($m); }
  76. Object Oriented Interface

  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
  78. Breaking Iteration

  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 <file>
  80. Shapes

  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<string, string>, 'data' => shape ( 'GET' => ?Map<string, mixed>, 'POST' => ?Map<string, mixed>, 'COOKIE' => ?Map<string, mixed>, 'SERVER' => Map<string, mixed> ), 'body' => ?string );
  82. Anonymous Functions

  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 = <ul/>; array_walk($items, $item ==> $list->appendChild(<li>{$item}</li>); ! echo $list;
  84. XHP — XML Fragments as Expressions

  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. <br /> XHP — XML Fragments as Expression echo <p>Hello World</p>;
  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.)
  87. Proprietary and Confidential The PHP Way <?php echo '<ul>'; foreach

    ($items as $item) { echo '<li>'; echo htmlentities($item, ENT_QUOTES, 'UTF-8'); echo '</li>'; } echo '</ul>'; ?>
  88. Proprietary and Confidential The Hack Way <?hh $list = <ul/>;

    foreach ($items as $item) { $list->appendChild(<li>{$item}</li>); }
  89. Proprietary and Confidential Feedback & Questions: ! 
 Twitter: @dshafik

    Email: davey@engineyard.com Slides: http://daveyshafik.com/slides
  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