20150203

PHP 7 RC — 성능 벤치 메모

PHP 7 alpha1이 지난달 말에 공개됐고 며칠 전 7.0.0alpha2가 나왔다. 어제 받아 로컬에서 돌려본 간단 벤치. RC 아직이고 alpha지만 이미 "2배" 소리가 돌아서 궁금했던 차.

테스트 환경: OSX 10.10, CPU i7 2.3GHz, 16GB. OPcache 켠 상태. 비교군은 5.6.4. 동일 php.ini(메모리 한도, opcache 설정) 유지. HHVM은 이번 라운드 제외.

벤치 결과. phoronix 식 쪽집게가 아니라 그냥 코드 몇 덩어리 돌린 수치.

bench.php (integer loop 1e7, Mandelbrot)
  PHP 5.6.4        3.12s
  PHP 7.0.0alpha2  1.48s

array_fill + array_sum (n=1e6, 10회)
  PHP 5.6.4        0.58s
  PHP 7.0.0alpha2  0.29s

문자열 결합 (str . str, 1e6회)
  PHP 5.6.4        0.41s
  PHP 7.0.0alpha2  0.22s

Laravel 5 스타일 라우팅 에뮬 (1000회 resolve)
  PHP 5.6.4        0.92s
  PHP 7.0.0alpha2  0.47s

json_decode (300KB 페이로드, 500회)
  PHP 5.6.4        1.18s
  PHP 7.0.0alpha2  0.71s

대략 1.7~2.1배. 초기에 떠돌던 "HHVM급" 주장에 근접한 시나리오도 있고 아닌 것도 있음. 메모리 사용량도 눈에 띄게 줄었다. 배열 위주 워크로드에선 RSS 30~40% 감소.

왜 이렇게 빠른가. 핵심은 phpng 브랜치로 시작한 Zend 엔진 리팩토링. 특히 zval 구조체 재설계가 크다. 5.x에서 zval은 값 + 타입 + refcount를 묶은 24바이트(64비트 기준) 구조에 포인터로 간접접근. 7에선 16바이트로 줄이고 가능하면 포인터 경유 없이 스택/인라인으로 처리. 메모리 footprint, 캐시 미스, allocator 호출이 줄어든다.

배열(HashTable)도 전면 리팩토링. 5.x HashTable은 내부 연결 리스트 기반에 버킷마다 포인터 난무였는데, 7에서는 연속된 배열(Zend array)로 바꿔 캐시 친화적. 특히 array_sum, foreach 같은 순회 벤치에서 격차가 벌어지는 이유.

함수 호출 오버헤드도 개선. execute_data에 오버플로우 체크 하나 줄이는 식의 microoptimization이 수백 개 쌓여 있다.

깨지는 것들. 안 아프게 넘어가진 못함.

  • mysql_* 확장 제거. PDO나 mysqli로 이관 필요. 회사 레거시에 아직 많이 남아있어서 할 일
  • 동일 표현식 안에서 $arr[$i][$j]의 평가 순서 변경(uniform variable syntax). $$foo['bar'] 같은 애매한 표현이 다르게 해석됨
  • 스칼라 타입 선언(int, float, string, bool) 도입. strict_types=1 선언 시 엄격 매칭
  • <? short open tag 관련 동작 정리, asp tag 제거
  • 예외 계층에 Error 추가(TypeError, ParseError 등 치명적 런타임 에러를 catch 가능). 기존 error_handler로 fatal을 잡던 코드는 동작 달라짐
  • Null coalescing(??), spaceship(<=>) 연산자 도입

라이브러리 호환성은 프레임워크마다 속도 차이가 있다. Symfony는 2.7 LTS가 PHP 7 호환 작업을 이미 많이 했고, Laravel은 5.1 기준 대체로 도는 편. 레거시 코드베이스는 php7cc(Migration Checker) 돌려보면 대략 경고 목록 뽑혀 나옴.

회사 서비스는 5.6 위에서 도는데 프로덕션 7 전환은 GA 나오고 6개월 관찰 후가 안전. 일단 개인 프로젝트 하나(작은 API 서버)를 7로 먼저 올려본다. 그 과정에서 써드파티 라이브러리 이슈 리포트할거 쌓이면 차차 업스트림에 PR.

한 가지 걸리는 건 HHVM. Facebook이 계속 밀고 있고 JIT라 특정 부하에선 여전히 7보다 빠른 구간이 있을텐데, 생태계 호환성(특히 PDO/MySQL 드라이버, 흔하지 않은 확장들) 때문에 프로덕션 전환 비용이 크다. 7 GA가 더 현실적인 선택지로 보임.