ipc 2013 - high performance php with hiphop

Download IPC 2013 - High Performance PHP with HipHop

If you can't read please download the document

Upload: steve-kamerman

Post on 16-Apr-2017

6.998 views

Category:

Technology


1 download

TRANSCRIPT

Steve Kamerman | ScientiaMobile, Inc.High-Performance PHP with HipHopCo-Founder / Software Architect

2008 - Facebook's Challenge

Explosive growth

Need more servers!

Bottleneck: Page generation

20% of PHP time was in native code

Why is PHP so slow?

Symbol table lookups

No static binding

Dynamic typing

Share-Nothing-Architecture

2008-2010 HipHop for PHP is born

400 Billion PHP-generated pageviews per month!

Facebook invents HipHop for PHP

Deployed system-wide in 2010

154k/second, or 154/sec per server on 1000 servers

HPHPc

Research &
Development

HHVM

HipHop for PHP

What is HipHop for PHP?

Multi-threaded web server + PHP runtime

HPHPc: PHP -> C++ translator

HHVM: PHP virtual machine with JIT compiler

Typically 2x 5x speed increase over stock PHP + APC

HipHop for PHP Compiler (HPHPc)

Translates PHP code into C++

Dynamic typing makes this difficult

Function parity lacking

Long compilation time

Literally translated PHP code into human-readable C++, preserving class names

At Facebook, PHP and C++ are common languages, so this works well

Many versions of each function may be generated with different parameter types to optimized code

Compilation at Facebook took 20min (across 100 machines)

Our Experience

Created WURFL Cloud REST API

Evaluated HPHPc

Improved Latency

Stability issues

Architecture

InternetHAProxy
Load Balancer
(primary)HAProxy
Load Balancer
(secondary)

WURFL NodeApacheHPHPcMemcachedMySQLWURFL NodeApacheHPHPcMemcachedMySQLWURFL NodeApacheHPHPcMemcachedMySQLWURFL NodeApacheHPHPcMemcachedMySQL

Codebase Updates

http://www.github.com/kamermans/HAProxyAPI

Facebook was customer

Reduced latency from 20ms (Apache) to 2m

Peak traffic over 1500 req/sec, load tested at over 10k req/sec per serverCode rebuild took almost 10 minutes per server

HPHP and Apache shared the same document root

Compilation of HPHP itself was painful! Super-specific dependencies

Next-Gen HipHop: HHVM

Virtual Machine

Better PHP Support

JIT Compiler

Bytecode Survives Restart

How HHVM works

InternetHHVM

Web ServerGenerate
BytecodeJIT Compile

Run Native
Code

Run Bytecode

HHVM vs HPHPc Performance

https://github.com/facebook/hhvm/blob/master/hphp/doc/ir.specification

http://www.hhvm.com/blog/875/wow-hhvm-is-fast-too-bad-it-doesnt-run-my-code

Optimizing PHP for HHVM

Type InferencePHP Gotcha: core function fail with (bool)false

HHVM Upgrades primitives

Use strict comparison

Don't care about type strict comparison?
You should. Trust me.


var_export("true" == true); // true
var_export("false" == true); // true
var_export("true" == (bool)"false"); // true
var_export(strpos("Steve Kamerman", "Kamerman") == true); // true
var_export(strpos("Steve Kamerman", "Steve") == true); // false
$test = "31 is too old!";
var_export(31 == $test); // true
var_export("31.0" == 31); // true
var_export("031" == 031); // false
var_export(31.0 == 31); // true
var_export($test += 1); // 32

Avoid global scope

Code in the global scope is interpreted since it is (nearly) impossible to type-track

Even wrapping global code helps:

class foo{public static function bar(){
$something = "test";
echo $something;
}}foo::bar();Better approach: dont write crappy code!

Unique Classes, Functions, Constants

HHVM supports namespaces use them!

MyApp\Bar and MyApp\Foo\Bar are not ambiguous

Avoid dynamic constants:
define("MY_CONST", $foo? "foo": "bar");

I can almost picture a feature request for undefine() and redefine()

If they are truly constant, use const

Better approach: don't use define()

namespace MyApp; class Config {

const MY_CONST = "I'm real constant";

private static $storage = array(
"PSEUDO_CONSTANT" => "What did you call me?",
);

public static function get($name) {
if (!array_key_exists($name, self::$storage)) {
throw new \Exception(__CLASS__." property [$name] does not exist");
}
return self::$storage[$name];
}
}

echo Config::MY_CONST."\n";
echo Config::get("PSEUDO_CONSTANT")."\n";

Avoid dynamic variables

If you are using this syntax, there is a better way to solve the problem:

$foo = "Wow, this hurts my brain!";
$var_name = "foo";
echo $$var_name;

extract() and compact() are sometimes used more legitimately (ex: view rendering), but avoid them

If you need get_defined_vars() for non-testing code, you need to rewrite it before someone sees it :)

Declare class properties

They should be declared anyway

$foo = new stdClass();
echo $foo->bar; // PHP Notice: Undefined property

Getters are optimized

Perfomance Gain

Less than 5%, but still good practice

Sub-optimal functions still work, even eval() and goto!

http://php.net/manual/en/control-structures.goto.php

Repo.Authoritative Mode

Pre-Analyze files

PHP files assumed unchanged

Delete cache manually

To use:

Analyze:hhvm --hphp --target hhbc --input-list