Join GitHub today
This page will be a collection of wisdoms about how to get even more speed out of HHVM if you're willing to put some effort in. The percentages are just empirically what average speedups people have seen.
You may also want to look into profiling and optimizing the code actually running on HHVM.
Use RepoAuthoritative - 20%
It is strongly recommended to enable RepoAuthoritative mode on production servers running HHVM.
Normally, when HHVM receives a request, it dynamically finds the source code, compiles it and any files it requires on the fly, and then executes them. This is a good flow for development. However, if HHVM can know ahead-of-time what files exist, it can do some precomputation and apply a lot of optimizations that are impossible without ahead-of-time knowledge of all source code. Such optimizations include function inlining (which requires knowing the inlined function won't change), optimizations to the memory layout of objects (which benefits from knowing what member variables may be defined), and many more.
Enabling RepoAuthoritative mode involves pre-compiling all of your source code into a bytecode repo. HHVM then consults only this repo, and not your source code, when servicing web requests. This comes with an often dramatic performance improvement due to the optimizations involved, but means that changes to source code won't take effect until the repo is rebuilt.
Since it's made a bunch of assumptions about what code exists,
create_function do not work in RepoAuthoritative mode.
As of HHVM 3.8, we provide a shell script to make this easy. To enable RepoAuthoritative mode use the
hhvm-repo-mode script provided with our Debian and Ubuntu packages. Give it the
enable command, followed by the path to your project's source code root -- probably
/usr/share/nginx/html. It will compile the repo, change the relevant HHVM configuration, and restart HHVM all automatically. (Since it changes HHVM configuration, you will probably need to be root to run it.) An example invocation might look like:
sudo hhvm-repo-mode enable /var/www
sudo hhvm-repo-mode disable
Although the above script is easy, for more advanced HHVM deployments, the recommended way to use RepoAuthoritative mode is to develop with it disabled, and then to build and deploy a repo, not source code, to production machines.
If you have PHP files
file2.php, you can build a bytecode archive named
hhvm.hhbc by executing this command:
hhvm --hphp -thhbc -o some_dir file1.php file2.php
Now you will have a pre-compiled repo file named
some_dir/hhvm.hhbc. The file
hhvm.hhbc is actually an sqlite database file - you can even view the structure of the file using sqlite. This is similar to a java
.jar or a python
.par file. It is a stand-alone version of your scripts. To run the program
file1.php, use this command:
hhvm -vRepo.Authoritative=true -vRepo.Central.Path=some_dir/hhvm.hhbc file1.php
To run the program
file2.php, use this command:
hhvm -vRepo.Authoritative=true -vRepo.Central.Path=some_dir/hhvm.hhbc file2.php
Note: If you get the error message
Unable to find/load systemlib.php, make sure you are pointing at the
hhvm.hhbc file and not the directory.
Warm up your server - 10%
The cache locality of the JITted code is very important, and you want all your important endpoints code to be located close to each other in memory. The best way to accomplish this is to pick your most important requests (say 5) and cycle through them all serially until you've done them all 12 times. Something like
for i in `seq 12`; do while read url; do curl "$url" done < important_urls.txt done
Do this every time you startup the server before it sees user traffic.
TODO: HHVM has a "warmup requests" feature which can do this more effectively, and automatically. We should document it. This issue has some information on how one person did it.