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/

Jeremy Mikola

May 08, 2015
Tweet

More Decks by Jeremy Mikola

Other Decks in Programming

Transcript

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

    → x64 Developer tools Interpreter (HPHPi) Debugger (HPHPd)
  2. 2013 HHVM replaces HPHPc in production HHVM 2.3.0 adds support

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

    Hack 27 PHP framework test suites at 100% Tracking PHP HEAD
  4. Why Are We Still Using PHP? : “objective issues… which

    make me sad” PHP: A Fractal of Bad Design PHP Sadness
  5. 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
  6. 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
  7. Small Responses (7 KB) Requests / Second Response Time (ms)

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

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

    https://blog.liip.ch/archive/2013/10/29/hhvm-and-symfony2.html
  10. 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
  11. Platform Support 64-bit Linux: It just works™ Mac OS X:

    interpreter only Windows and ARM in development
  12. 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
  13. 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
  14. 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
  15. 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 ; } }
  16. 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 ; } }
  17. 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 ; } }
  18. 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 ; }
  19. 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
  20. 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 ( ) ) ; }
  21. 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 ) ; }
  22. Collections Specialized array objects Vector, Map, Set, Pair Ordered, immutable

    or mutable Accessible, iterable like PHP arrays Literal syntax, familiar collection API
  23. 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 }
  24. 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
  25. 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
  26. 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 ) ;
  27. 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 ) ; }
  28. 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 ) ; }
  29. 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 ( ) ;
  30. 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)
  31. 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/
  32. 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/
  33. 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
  34. 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
  35. 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
  36. 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