php - 종류 - 파이썬 클래스 메소드 호출




정적 메소드와 함수의 성능 비교 (4)

PHP를 마친 이후로 꽤 오랜 시간이 걸렸지 만 다른 프로그래밍 환경에서 기대했던 것과 비슷할 것입니다.

정적 메서드는 호출 될 때마다 장면 뒤에 SomeClass 개체의 일부 구성이 필요하지만 시작 비용없이 함수를 실행할 수 있습니다. 객체 생성은 가비지 컬렉터 / 참조 카운터에 의한 기존 객체의 파괴, C 런타임의 차선 메모리 할당 정책 등 메모리 압박을 일으키는 많은 것들에 따라 비용이 많이들 있습니다.

기존 객체의 메소드 성능을 비교하는 것은 흥미로울 것입니다. 이렇게하려면 SomeClass의 인스턴스를 만든 다음 인스턴스 메서드를 반복적으로 호출합니다.

PHP에서는 (원래 생각했던 것과는 달리) 정적 메서드와 간단한 함수를 호출하는 오버 헤드가 있습니다.

매우 간단한 벤치에서 오버 헤드는 호출 시간의 30 % 이상입니다 (이 메서드는 매개 변수를 반환합니다).

// bench static method
$starttime = microtime(true);
for ($i = 0; $i< 10*1000*1000; $i++)
    SomeClass::doTest($i);

echo "Static Time:   " , (microtime(true)-$starttime) , " ms\n";

// bench object method
$starttime = microtime(true);

for ($i = 0; $i< 10*1000*1000; $i++)
    $someObj->doTest($i);

echo "Object Time:   " , (microtime(true)-$starttime) , " ms\n";

// bench function
$starttime = microtime(true);

for ($i = 0; $i< 10*1000*1000; $i++)
    something_doTest($i);

echo "Function Time: " , (microtime(true)-$starttime) , " ms\n";

출력 :

Static Time:   0.640204906464 ms
Object Time:   0.48961687088 ms
Function Time: 0.438289880753 ms

나는 실제 무언가가 실제로 백만 시간을 부르지 않으면 실제 시간은 여전히 ​​무시할 만하다. 그러나 사실은 그 시간이다.

배후에서 무슨 일이 일어나고 있는지 설명하는 사람은 누구입니까?

최신 정보:
- 추가 된 객체 메소드 벤치


내 컴퓨터에서 여러 번 테스트를 반복했고 놀랍게도 당신이 옳습니다!

PHP에서 static 클래스의 메서드 호출은 개체 메서드를 호출하는 것보다 느린 것 같습니다. 간단한 테스트는 여기를 클릭하십시오.

실행중인 테스트의 코드는 위의 링크에 있습니다.

심지어 objet 메서드와 정적 메서드를 같은 클래스에 배치하려고 시도했지만 static 메서드는 여전히 저조한 결과를 초래했습니다.

이 시점에서 상속 클래스가 지연을 더하기 때문에 천천히 상속 된 클래스의 static 메서드에 대한 호출이 될 수 있는지 궁금합니다.

슬프게도, 나는 그 이유에 대해 단서가 없다. 어쩌면 PHP는 static 메서드의 정의를 찾는 데 더 많은 시간이 걸릴 것 입니다.

부차적 인 언급으로 나는 실제 애플리케이션에서 대개 그 메소드 중 하나를 호출하기 전에 객체를 생성한다고 만 말할 수 있습니다. 그러므로 테스트 할 때마다 정적 호출 루프를 매번 (또는 적어도 몇 번 ) [*] 객체를 생성하는 루프와 비교하여 테스트해야합니다.

for($i=0; $i<10*1000*1000; $i++)
{ 
   $someObj = new someObj();
   $someObj->doTest($i); 
}

따라서 static 호출보다 분명히 느립니다.

for($i=0; $i<10*1000*1000; $i++)
{ 
   SomeClass::doTest($i);
}

[*] 문제는 실제 애플 리케이션에서 어떤 happnes를 시뮬레이션하기 위해 몇 번 정도 입니까? 말하기 어렵다!


분명히이 점은 이후 버전의 PHP (5.5.12)에서 수정되었습니다.

나는 OP의 코드를 (빈 메소드를 사용하여) 실행했고, 다음 결과를 얻었다 :

Static Time:   1.0153820514679 ms
Object Time:   1.100515127182 ms

편집 : 나중에 8 개월 및 일부 릴리스 ...

Zend와 커뮤니티가 PHP의 성능에 대해 열심히 노력하고있는 것을 보는 것은 흥미로운 일입니다.

🐘 PHP 5.6

다음은 PHP 5.6.9 (ZE 2.6)와 동일한 벤치 마크입니다.

Static Time:   0.97488021850586 ms
Object Time:   1.0362110137939 ms
Function Time: 0.96977496147156 ms

한 번의 실행에서 "객체 시간"은 정적 시간보다 훨씬 빠르기 때문에 지금은 매우 가깝습니다. 더 좋게, 우리는 객체가 함수로서 거의 빠르다는 것을 알 수 있습니다!

🐘 PHP 7.0

필자는 PHP 7.0 alpha 1 (ZE 3.0)을 컴파일했으며, PHP 같은 빠른 언어 ( here 또는 here 볼 수있는 다른 동적 언어와 비교할 때) 가 반복적으로 최적화 될 수 있다는 것을 보아서 놀랍습니다.

Static Time:   0.33447790145874 ms
Object Time:   0.30291485786438 ms
Function Time: 0.2329089641571 ms

PHP7에서는 기본 함수가 크게 최적화되었으며 "정적 시간"은 "인스턴스 / 객체 시간"보다 느립니다.

편집, 1 년 후인 2015 년 10 월 : PHP 7.0 RC5 . 이제는 "정적 시간"이 빠릅니다. 주의해야 할 중요한 점은 스칼라 타입 힌팅 (PHP7의 새로운 기능)은 상당한 오버 헤드를 가져옵니다. 약 16 % 느려집니다 (타입 힌팅은 코드를 16 % 느리게 만들지 않습니다. 코드가 함수 호출로만 구성되어있을 때는 느려집니다. ) 실생활 어플리케이션에서는 무시해도됩니다. 이러한 오버 헤드는 비논리적 인 것처럼 보일 수 있지만, 동적 타이핑이 PHP의 핵심에 있다는 것을 알면 덜 놀라게됩니다. 다른 정적 인 언어와는 달리, PHP에서 타입 힌트는 Zend Engine에 대한 더 많은 검사를 의미하며, 우리 중 일부는 기대할 수있는 것 보다 적습니다 . 앞으로 HHVM의 런타임 코드 분석 및 JiT 접근 방식과 마찬가지로이 시점에서 더 많은 런타임 최적화를 얻게 될 것입니다. PHP7이 젊다는 것을 잊지 말자. 그리고이 릴리스에서 수행 된 모든 정리 작업으로 인해 기능과 성능이 크게 향상 될 것입니다.

🐘HHVM

HHVM 3.7.1 에 대한 테스트는 HHVM 3.7.1 이러한 유형의 벤치 마크에서 쉽게 승리한다는 것을 보여줍니다. 여기에서 JiT 컴파일의 이점을 볼 수 있습니다 (JiT는 향후 버전의 PHP를위한 "계획된"기능입니다. 7.x 또는 8.x 브랜치 Zend는 OpCache 확장 기능으로 PoC를 만들었습니다 .)

Static Time:   0.070882797241211 ms
Object Time:   0.23940300941467 ms
Function Time: 0.06760311126709 ms

HHVM의 경우, 함수와 정적 메소드의 타이밍이 매우 비슷하기 때문에, 내부적으로는 거의 같은 것으로 생각할 수 있습니다 (결국 정적 메소드는 네임 스페이스 함수와 매우 유사합니다). 인스턴스 타이밍은 다른 것보다 "재앙"입니다. 이것은 HHVM과 ZE가 매우 다른 엔진 인 방법을 보여줍니다.

결론?

이러한 관행 (정적 / 인스턴스) 중 하나가 더 빨리 영원히 머물 것이라는 보장은 없습니다. 소프트웨어 디자인 측면에서 가장 잘 보이는 것을 사용하고 일관된 코드를 기존 응용 프로그램에 보관하십시오.

선택의 여지가 있거나 도서관 등을 작성하는 경우 인스턴스 메소드를 사용할 수 있고 DI 환경에 더욱 친숙하며 API를 사용하는 개발자에게 더 많은 제어권을 제공합니다.

npm의 생태계에있는 작은 패키지와 같은 유틸리티 기능을 제공하는 경우 네임 스페이스가있는 함수를 사용할 수 있습니다 ( PHP는 여전히 함수 자동 로딩 기능을 가지고 있지 않으므로 작성자가 다음 과 같이 라이브러리를 느리게로드 할 수 없음을 의미합니다). 그것은 PSR-0 / 4로합니다)






oop