PHP 오프코드: 코드를 변경하지 않고 애플리케이션 성능 향상

PHP 엔진이 생성하는 PHP 오픈 코드는 Task를 accomplish하기 위한 声明의 수 alone로는 결정되지 않고, 코드를 쓸 때 사용하는 방법에 따라 강하게 영향을 받는다. 명확하게 어느 정도의 문제가 있으며, 이에 대해 당신에게도 显然하다고 생각한다.

보다 명확하게 하는 것은 코드의 문법 itself가 생성되는 오픈 코드를 완전히 바꿀 수 있어 같은 코드를 실행하기 위해서는 시스템의 CPU에 많은 오버헤드가 발생하는 것이다.

지난 몇 해에 내 SaaS 제품이 많이 成长し、내가 어느 정도의 성능 優化 기술을 적용할 수 있는 기회를 얻었다.

나는 보여준 결과가 감동적이었고 내 SaaS 鞍ب该公司 를 진행하는 데 어느 정도의 自由的 cash flow를 발 unlock하는 데 도움이 많이 돤었다.

이 지점에서, 내 SaaS 제품 내의 PHP 프로세스는 2vCPU와 8GB의 메모리를 갖춘 기기上에서 每天 12억(“b”로 표기) 단위의 데이터 패킷을 처리하고 있다. AWS 자동 ス케일링 그룹을 사용하여 예측할 수 없는 突然 등장하는 것을 대응할 수 있는 更大的 靈活성을 얻고 있지만, 그 대신 두 번에 한 번씩 두 번째 기기를 추가하는 것뿐이다(주로 週刊 한/두 번).

이제 글의 주제로 들어가 보자. 당신에게는 매우 興味深い 것이라고 생각한다.

PHP Opcode는 무엇인가?

PHP Opcode는 opeation code의 의미로, PHP 소스 코드가 컴파일되어 실행되는 것 이전의 하 constitute low-level instructions를 의미한다.

PHP에서는 runtime에서 code compilation이 일어나고 있다: 기본적으로, 당신의 코드가 PHP 엔진에 들어가는 첫 번째 날에는 이를 기계가 좋아하는 코드로 컴파일하고, 같은 코드를 다시 컴파일하지 않게 cache하고, 그 다음에 실행하게 된다.

다음은 프로세스의 간단한 표현입니다:

PHP Opcode 캐싱

PHP opcode 캐싱을 통해 코드를 실행하는 과정에서 세 단계를 생략할 수 있습니다. 원시 PHP 코드 파싱, 토큰화 및 컴파일입니다.

opcode가 처음 생성되면 메모리에 저장되어 이후 요청에서 재사용할 수 있습니다. 이렇게 하면 PHP 엔진이 동일한 PHP 코드를 매번 다시 컴파일할 필요가 줄어들어 CPU 및 메모리 사용량을 크게 줄일 수 있습니다.

PHP에서 가장 일반적으로 사용되는 opcode 캐시는 OPCache이며, PHP 5.5부터 최신 버전까지 기본적으로 포함되어 있습니다. 매우 효율적이고 널리 지원됩니다.

사전 컴파일된 스크립트 바이트 코드를 캐싱하려면 배포 후 캐시를 무효화해야 합니다. 변경된 파일이 캐시에 바이트 코드 버전이 있으면 PHP가 캐시에서 이전 버전의 코드를 계속 실행하기 때문에 캐시를 지우지 않으면 새 코드가 컴파일되어 새로운 캐시 항목이 생성되지 않습니다.

PHP Opcode 조사 방법

다른 구문이 스크립트의 opcode에 미치는 영향을 이해하려면 PHP 엔진에서 생성된 컴파일된 코드를 가져올 방법이 필요합니다.

opcode를 가져오는 방법은 두 가지입니다.

OPCache 네이티브 함수

기계에 OPCache 확장을 사용하고 있다면 해당 네이티브 함수를 사용하여 특정 PHP 파일의 opcode를 가져올 수 있습니다:

PHP

 

VLD(Vulcan Logic Disassembler) PHP 확장

VLD는 컴파일된 PHP 코드를 분석하고 오PCode를 출력하는 인기있는 PHP 확장입니다. PHP가 어떻게 interpret하고 실행하는지 이해하는 強力한 도구입니다. 설치 한 후, PHP 스크립트를 VLD을 사용해서 실행할 수 있습니다. php 명령어에 -d 옵션을 사용하여 이를 실행합니다:

Shell

 

출력은 컴파일된 오PCode에 관한 자세한 정보를 包括하고 있습니다. 각 연산, 그에 대응하는 코드 줄 등을 보여줍니다.

3v4l(EVAL의 약자)을 사용하세요

3v4l는 PHP 코드가 생성하는 오PCode를 볼 수 있는 유용한 온라인 도구입니다. 기본적으로 PHP 서버로 구성되어 있으며 VLD을 설치하여 VLD 출력을 사용하여 브라우저에서 오PCode를 보여주는 것입니다.

이 무료이기 때문에 다음 분석에서 이 온라인 도구를 사용할 것입니다.

효율적인 PHP 오PCode를 생성하는 方法

3v4l은 우리가 사용하는 코드 문법이 결과적인 PHP 오PCode에 어떻게 영향을 미치는지 이해하는 것에 완벽합니다. 코드를 아래에 붙여넣고 “모든 지원 버전” 구성을 유지하고 “eval”을 클릭하세요.

PHP

 

코드를 실행한 후, 하단에 탭 메뉴가 나타납니다. 이 탭을 VLD 탭으로 이동하여 相应的 Opcode를 시각적으로 보세요.

Shell

 

첫 번째 operration은 INIT_NS_FCALL_BY_NAME입니다. 인터preter는 현재 파일의 namespace를 사용하여 함수의 이름을 構築하지만, App\Example namespace에 해당하는 것이 없습니다. 그렇다면 어떻게 작동하는지 어떻게 되나요?

인터preter는 현재 namespace에 함수가 存在하는지 확인합니다. 如果不存在, 그는 相应的 core function을 호출하려고 시도합니다.

여기에서는 인터preter로 이 쌍으로의 확인을 避免하고 직접 core function을 실행하도록 알려줄 수 있습니다.

strlen에 백스lash(\)을 추가하고 “eval“를 클릭하십시오.

PHP

 

VLD 탭에서는 이제 한 문장의 opcode를 보실 수 있습니다.

因为你 함수의 정확한 위치를 알려주었기 때문에, allback을 고려할 필요가 없습니다.

백스lash을 사용하지 않고 싶다면, root namespace에 있는 다른 클래스와 마찬가지로 함수를 導入할 수 있습니다.

PHP

 

Automatic Opcode Optimizations을 이용하십시오.

PHP engine에서 static expressions을 예전에 평가하여 optimized opcode를 생성하는 많은 내부 자동机制이 存在하며, PHP 7.x 이전과 비교해서 큰 성능 improvment을 위한 가장 중요한 이유였습니다.

이러한 동적성을 알고 있다면, 리소스 CONSUMPTION을 줄이고 COST를 절감할 수 있습니다. 이러한 연구를 마친 후에, 저는 이러한 기술을 코드 전체에 적용하기 시작했습니다.

PHP 상수를 사용하는 예제를 보여드릴 것입니다. 이 스크립트를 3v4l에 运行시키십시오.

PHP

 

PHP opcode의 첫 두 行을 보십시오.

FETCH_CONSTANT는 현재 네임스페이스에서 PHP_OS의 값을 가져오려고 시도하며, 여기서 존재하지 않으면 글로벌 네임스페이스를 살펴봅니다. 그런 다음 IS_IDENTICAL 명령어가 IF 문을 실행합니다.

이제 상수에 백슬래시를 추가해보세요:

PHP

 

보시다시피, 엔진은 상수가 어디에 있는지 분명하므로 상수를 가져오려고 시도할 필요가 없으며, 이는 정적 값이므로 이미 메모리에 가지고 있습니다.

또한, IF 문이 사라졌습니다. 왜냐하면 IS_IDENTICAL 문장의 다른 쪽이 정적 문자열(‘Linux’)이기 때문에 IF는 매번 실행할 때마다 해석하는 오버헤드 없이 “true”로 표시될 수 있기 때문입니다.

이것이 PHP 코드의 궁극적인 성능에 많은 영향을 미칠 수 있는 이유입니다.

결론

흥미로운 주제였기를 바랍니다. 기사 초반에 언급했듯이 이 전술을 사용하여 많은 이점을 얻고 있으며, 사실 우리 패키지에서도 사용되고 있습니다.

여기서 예제를 볼 수 있습니다 제가 이러한 팁을 사용하여 PHP 패키지의 성능을 최적화한 방법을.

개발자 중심의 회사를 구축하는 도전 과제에 대해 더 알고 싶다면, LinkedIn에서 저를 팔로우할 수 있습니다.

Source:
https://dzone.com/articles/php-opcode-improve-application-performance