Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A New Type of PHP: HHVM and Hack

A New Type of PHP: HHVM and Hack

Presented May 8, 2015 at OpenWest: http://joind.in/talk/view/14032

Presented July 14, 2014 at Midwest.io: http://www.midwest.io/archive/2014/sessions/#monday-2a

Reveal.js presentation published at: http://jmikola.github.io/slides/hhvm_and_hack/

F23700b51dc0c196c1dc02f84aeeecdf?s=128

Jeremy Mikola

May 08, 2015
Tweet

Transcript

  1. A NEW TYPE OF PHP: HHVM AND HACK Jeremy Mikola

    jmikola
  2. A Brief History of Time

  3. 2008 HipHop PHP compiler (HPHPc) PHP → AST → C++

    → x64 Developer tools Interpreter (HPHPi) Debugger (HPHPd)
  4. 2010 Facebook open-sources HPHPc HipHop Virtual Machine (HHVM) PHP →

    AST → HHBC HHBC → x64 (JIT)
  5. 2011 Facebook open-sources HHVM HHVM replaces HPHPi for development

  6. 2012

  7. 2013 HHVM replaces HPHPc in production HHVM 2.3.0 adds support

    for FastCGI Travis CI adds HHVM runtime Performance and parity lockdowns
  8. 2014 Facebook open-sources Hack language HHVM 3.0.0 adds support for

    Hack 27 PHP framework test suites at 100% Tracking PHP HEAD
  9. HHVM

  10. Why Are We Still Using PHP? : “objective issues… which

    make me sad” PHP: A Fractal of Bad Design PHP Sadness
  11. The Elephant in the Room It’s had a role in

    significant projects Wikipedia, Drupal, Wordpress Facebook: x * 10⁵ files, y * 10⁷ LOC It gets some things right Developer workflow: tight feedback loop State: each request is a blank slate Concurrency: share nothing Taking PHP Seriously – Keith Adams, Facebook
  12. Lifetime of a Request

  13. Bytecode Interpreter

  14. Native Code JIT

  15. Repo Authoritative Pre-compile HHBC: h h v m - -

    h p h p - t a n a l y z e
  16. Benchmarking HHVM

  17. Test Environment Symfony2, ElasticSearch (HTTP API) JSON → PHP serialization

    PHP 5.3 (APC), PHP 5.5 (OpCache), HHVM 2.3.0 nginx web server with FastCGI ApacheBench for load testing Results from: , Christian Stocker Liip AG
  18. Small Responses (7 KB) Requests / Second Response Time (ms)

    https://blog.liip.ch/archive/2013/10/29/hhvm-and-symfony2.html
  19. Medium Responses (80 KB) Requests / Second Response Time (ms)

    https://blog.liip.ch/archive/2013/10/29/hhvm-and-symfony2.html
  20. Large Responses (220 KB) Requests / Second Response Time (ms)

    https://blog.liip.ch/archive/2013/10/29/hhvm-and-symfony2.html
  21. Some Conclusions PHP 5.5 is up to 1.5 times faster

    than PHP 5.3 HHVM is up to 3.5 times faster than PHP 5.3 HHVM is up to twice as fast as PHP 5.5 HHVM shines under high load, larger requests Stop using PHP 5.3
  22. Installing HHVM

  23. Platform Support 64-bit Linux: It just works™ Mac OS X:

    interpreter only Windows and ARM in development
  24. Linux Binaries Ubuntu (LTS, recent releases) Debian 8 Fedora 20

    Mint 16 CentOS (community supported)
  25. Building from Source Fair amount of dependencies A must for

    extension development $ g i t c l o n e g i t : / / g i t h u b . c o m / f a c e b o o k / h h v m . g i t $ c d h h v m $ g i t c h e c k o u t H H V M - 3 . 1 . 0 $ g i t s u b m o d u l e u p d a t e - - i n i t - - r e c u r s i v e $ c m a k e . $ m a k e - j [ n u m _ c o r e s ] $ s u d o m a k e i n s t a l l
  26. Grab a Snickers…

  27. HACK < ? h h

  28. In a Nutshell Static type analysis Local type inference, meaningful

    errors Tight feedback loop (h h _ c l i e n t , h h _ s e r v e r ) Checked before runtime New language features, core classes Some PHP ‘features’ removed Catch bugs early, develop faster
  29. Wonderful World of Types

  30. Type Hinting Scalars bool, int, float, num, string Array elements

    (and keys) a r r a y < i n t > , a r r a y < s t r i n g , i n t > Properties and return types Nullable and m i x e d types Generics lend to code reuse
  31. Type Hinting c l a s s A d d

    e r { p r i v a t e i n t $ x ; p u b l i c f u n c t i o n _ _ c o n s t r u c t ( i n t $ x ) : v o i d { $ t h i s - > x = $ x ; } p u b l i c f u n c t i o n a d d ( i n t $ y ) : v o i d { $ t h i s - > x + = $ y ; } p u b l i c f u n c t i o n g e t ( ) : i n t { r e t u r n $ t h i s - > x ; } }
  32. Constructor Arg Promotion c l a s s A d

    d e r { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( p r i v a t e i n t $ x ) : v o i d { } p u b l i c f u n c t i o n a d d ( i n t $ y ) : v o i d { $ t h i s - > x + = $ y ; } p u b l i c f u n c t i o n g e t ( ) : i n t { r e t u r n $ t h i s - > x ; } }
  33. Generics c l a s s A d d e

    r < T > { p u b l i c f u n c t i o n _ _ c o n s t r u c t ( p r i v a t e T $ x ) : v o i d { } p u b l i c f u n c t i o n a d d ( T $ y ) : v o i d { $ t h i s - > x + = $ y ; } p u b l i c f u n c t i o n g e t ( ) : T { r e t u r n $ t h i s - > x ; } }
  34. Type Aliasing Declared outside of classes, functions Opaque aliasing abstracts

    underlying type / / t y p e s . p h p t y p e M y I n t = i n t ; n e w t y p e M y O p a q u e I n t = i n t ; r e q u i r e ' t y p e s . p h p ' ; f u n c t i o n f o o ( M y I n t $ x ) : M y I n t { r e t u r n $ x + 1 ; } f u n c t i o n b a r ( M y O p a q u e I n t $ x ) : M y O p a q u e I n t { / / E r r o r : c a n n o t a s s u m e i n t e g e r b e h a v i o r o u t s i d e o f t y p e s . p h p r e t u r n $ x + 1 ; }
  35. Type Checking is Configurable Modes: strict, partial, decl < ?

    h h / / m o d e Partial is most flexible, the default Classes and functions can be partially typed Allows calling into untyped code (i.e. PHP) Decl useful for calling into legacy code from strict Type checker looks at signatures, but not code
  36. Stop Using PHP Arrays (ab)

  37. Tuples Typed, fixed-length lists Size and types are immutable Useful

    for custom types, multiple return values t y p e P o i n t 2 D = ( i n t , i n t ) ; f u n c t i o n c r e a t e P o i n t ( i n t $ x , i n t $ y ) : P o i n t 2 D { r e t u r n t u p l e ( $ x , $ y ) ; } f u n c t i o n g e t D a t e A n d T i m e s t a m p ( ) : ( s t r i n g , i n t ) { r e t u r n t u p l e ( d a t e ( ' c ' ) , t i m e ( ) ) ; }
  38. Shapes Typed, structured dictionaries Alternative to classes with public properties

    Useful for simple data structures, argument bags t y p e P a g e V i e w = s h a p e ( ' u r l ' = > s t r i n g , ' c o u n t ' = > i n t , ) ; f u n c t i o n c r e a t e P a g e V i e w ( s t r i n g $ u r l , i n t $ c o u n t ) : P a g e V i e w { r e t u r n s h a p e ( ' u r l ' = > $ u r l , ' c o u n t ' = > $ c o u n t ) ; }
  39. Collections Specialized array objects Vector, Map, Set, Pair Ordered, immutable

    or mutable Accessible, iterable like PHP arrays Literal syntax, familiar collection API
  40. Vectors vs. PHP Arrays $ v e c t o

    r = V e c t o r { 5 , 1 0 , 1 5 , 2 0 } ; $ v e c t o r - > r e m o v e K e y ( 2 ) ; f o r e a c h ( $ v e c t o r a s $ k e y = > $ v a l u e ) { p r i n t f ( " % d = > % d \ n " , $ k e y , $ v a l u e ) ; } $ a r r a y = [ 5 , 1 0 , 1 5 , 2 0 ] ; u n s e t ( $ a r r a y [ 2 ] ) ; f o r e a c h ( $ a r r a y a s $ k e y = > $ v a l u e ) { p r i n t f ( " % d = > % d \ n " , $ k e y , $ v a l u e ) ; } [ 5 , 1 0 , 2 0 ] vs. { " 0 " : 5 , " 1 " : 1 0 , " 3 " : 2 0 }
  41. These May Be Useful, Too

  42. Lambda Expressions PHP has closures, but… Parent scope is not

    implicitly inherited Can be verbose for simple expressions $ i n c = f u n c t i o n ( $ x ) { r e t u r n $ x + 1 ; } $ i n c ( 1 1 ) ; / / r e t u r n s 1 2 $ f = f u n c t i o n ( $ x ) { r e t u r n f u n c t i o n ( $ y ) u s e ( $ x ) { r e t u r n $ x + $ y ; } ; } ; $ g = $ f ( 4 ) ; $ g ( 5 ) ; / / r e t u r n s 9
  43. Lambda Expressions Parent scope is inherited automatically Concise syntax well-suited

    to callback APIs $ i n c = $ x = = > $ x + 1 ; $ i n c ( 1 1 ) ; / / r e t u r n s 1 2 $ f = $ x = = > $ y = = > $ x + $ y ; $ g = $ f ( 4 ) ; $ g ( 5 ) ; / / r e t u r n s 9
  44. Lambdas and Collections $ a r r a y =

    [ 2 , 4 , 6 , 8 ] ; $ i n c = 3 ; a r r a y _ f i l t e r ( a r r a y _ m a p ( f u n c t i o n ( $ x ) u s e ( $ i n c ) { r e t u r n $ x + $ i n c ; } , $ a r r a y ) , f u n c t i o n ( $ x ) { r e t u r n $ x > 1 0 ; } ) ; vs. $ v e c t o r = V e c t o r { 2 , 4 , 6 , 8 } ; $ i n c = 3 ; $ v e c t o r - > m a p ( $ x = = > $ x + $ i n c ) - > f i l t e r ( $ x = = > $ x > 1 0 ) ;
  45. Continuations Like generators in PHP 5.5, slight differences Must be

    primed with n e x t ( ) y i e l d must always return a value f u n c t i o n i n f i n i t e ( ) : C o n t i n u a t i o n < i n t > { $ i = 0 ; w h i l e ( t r u e ) { y i e l d $ i + + ; } } f o r e a c h ( i n f i n i t e ( ) a s $ i ) { p r i n t f ( " % d \ n " , $ i ) ; }
  46. Async Functions Functions use a s y n c modifier,

    return Awaitables Callers opt in with a w a i t keyword a s y n c f u n c t i o n c o m p l e x C a l c u l a t i o n ( … ) : A w a i t a b l e < R e s u l t > { / / q u e r y d a t a b a s e s , c a l l s e r v i c e s , e t c . r e t u r n n e w R e s u l t ( … ) ; } a s y n c f u n c t i o n f e t c h U s e r ( i n t $ i d ) : A w a i t a b l e < U s e r > { $ a r g s = [ ' i d ' = > $ i d , ' t y p e ' = > ' u s e r ' ] ; $ a = c o m p l e x C a l c u l a t i o n ( $ a r g s ) ; / / $ a r e p r e s e n t s u n s t a r t e d s t a t e o f a c o m p u t a t i o n $ r e s u l t = a w a i t $ a ; / / b l o c k u n t i l $ a i s r e s o l v e d r e t u r n c o n v e r t R e s u l t T o U s e r ( $ r e s u l t ) ; }
  47. Async Functions Parallelism by awaiting multiple things at once Top-level

    context can j o i n ( ) (block on results) a s y n c f u n c t i o n g e n e r a t e R e s p o n s e ( ) : A w a i t a b l e < R e s p o n s e > { l i s t ( $ a , $ b , $ c ) = a w a i t G e n A r r a y W a i t H a n d l e : : c r e a t e ( [ f e t c h U s e r ( … ) , q u e r y C a c h e ( … ) , c a l l S e r v i c e ( … ) , ] ) ; r e t u r n n e w R e s p o n s e ( $ a , $ b , $ c ) ; } a s y n c f u n c t i o n f e t c h U s e r ( … ) : A w a i t a b l e < … > { } a s y n c f u n c t i o n q u e r y C a c h e ( … ) : A w a i t a b l e < … > { } a s y n c f u n c t i o n c a l l S e r v i c e ( … ) : A w a i t a b l e < … > { } $ r e s p o n s e = g e n e r a t e R e s p o n s e ( ) - > j o i n ( ) ;
  48. Additional Features User attributes (accessible via Reflection) Trait requirements (support

    static analysis) Override attribute (child counterpart to abstract) Variadic arguments (not type-checked) XHP (templated XML fragments in PHP)
  49. Extending HHVM

  50. Creating an Extension Bootstrap PHP in SystemLib HHVM Native Interface

    (HNI) Dynamically Loaded Objects
  51. HHVM Native Interface (PHP) Implement as much as possible in

    PHP Annotated methods point to C++ implementations c l a s s M o n g o C l i e n t { < < _ _ N a t i v e > > p u b l i c f u n c t i o n _ _ c o n s t r u c t ( s t r i n g $ s e r v e r = ' m o n g o d b : / / l o c a l h o s t : 2 7 0 1 7 ' , a r r a y $ o p t i o n s = [ ' c o n n e c t ' = > t r u e ] ) : v o i d ; p u b l i c f u n c t i o n s e l e c t D B ( s t r i n g $ n a m e ) : M o n g o D B { r e t u r n n e w M o n g o D B ( $ t h i s , $ n a m e ) ; } / / … } https://github.com/10gen-labs/mongo-hhvm-driver/
  52. HHVM Native Interface (C++) Method macros similar to PHP extension

    API 1:1 mapping between PHP and C++ types s t a t i c v o i d H H V M _ M E T H O D ( M o n g o C l i e n t , _ _ c o n s t r u c t , c o n s t S t r i n g & u r i , A r r a y o p t i o n s ) { m o n g o c _ c l i e n t _ t * c l i e n t = m o n g o c _ c l i e n t _ n e w ( u r i . c _ s t r ( ) ) ; / / w r a p m o n g o c _ c l i e n t _ t i n a n H H V M r e s o u r c e o b j e c t t h i s _ - > o _ s e t ( " _ r e s o u r c e " , c l i e n t R e s o u r c e , " C l i e n t R e s o u r c e " ) ; } https://github.com/10gen-labs/mongo-hhvm-driver/
  53. Undocumented Territory Learn by example, consult prior art Core extensions

    (h p h p / r u n t i m e / e x t / ) Community extensions (about a dozen) Become an IRC regular
  54. Looking Ahead PHP iterating faster than ever Multiple implementations is

    a plus Competition drives progress Hack features and overlapping PHP RFCs Facebook still active on php-internals
  55. Getting the Community on Board http://hhvm.h4cc.de/

  56. PHPNG (Next Generation) JIT based on Fair amount of internal

    refactoring Some behavioral changes, BC breaks Progress since January 2014 1.5x execution speed-up 30–60% less CPU instructions LLVM
  57. THANKS! Any Questions? and and # h h v m

    on Freenode jmikola.net/blog/hack-dev-day/ github.com/facebook/hhvm wiki hhvm.com hacklang.org Thanks to: , , , and Elizabeth Smith Sara Golemon Christian Stocker Chris Heng
  58. Image Credits id Software (Doom character sprites) http://xkcd.com/303/