>백엔드 개발 >PHP 튜토리얼 >PHP 성능 최적화 예제 공유

PHP 성능 최적화 예제 공유

小云云
小云云원래의
2018-03-15 13:30:371586검색

이 문서에서는 주로 PHP 성능 최적화 예제를 공유하며 모든 사람에게 도움이 되기를 바랍니다.

1. 가능한 한 정적으로 만드세요:

메서드를 정적으로 선언하면 속도가 1/4까지 증가할 수 있습니다. 테스트를 했는데도 거의 3배나 빨라졌습니다.
물론 이 테스트 방법은 100,000레벨 이상에서 실행해야 효과가 뚜렷하게 나타납니다.
실제로 정적 메서드와 비정적 메서드 간 효율성의 주요 차이점은 메모리입니다. 정적 메서드는 프로그램이 시작될 때 메모리를 생성하고, 인스턴스 메서드는 프로그램이 실행되는 동안 메모리를 생성하므로 정적 메서드를 직접 호출할 수 있고, 인스턴스 메소드는 먼저 인스턴스를 생성하고 인스턴스를 전달해야 합니다. 메소드 호출은 정적으로 매우 빠르지만 너무 많으면 메모리를 차지하게 됩니다.
어떤 언어든 메모리와 디스크에서 작동하는지 여부는 소프트웨어 계층의 문제일 뿐입니다. 하지만 구현 방법이 다릅니다. 정적 메모리는 프로그램 시작 시 생성되기 때문에 연속적이지만, 인스턴스는 불연속적인 공간에 적용되므로 당연히 정적 방식만큼 빠르지는 않습니다.
정적 메서드는 항상 동일한 메모리를 호출합니다. 단점은 자동으로 소멸될 수 없지만 인스턴스화에 의해 소멸될 수 있다는 것입니다.

2. echo는 반환 값이 없고 print는 정수를 반환하기 때문에 print보다 더 효율적입니다.

테스트:
Echo
0.000929 - 0.001255초(평균 0.001092초)
인쇄
0.000980 - 0.001396초(평균) 0.0 01188초 )
차이는 약 8% 정도입니다. 일반적으로 에코가 더 빠릅니다.
큰 문자열을 에코할 때 조정을 하지 않으면 성능에 심각한 영향을 미칠 수 있다는 점에 유의하세요. 압축을 위해 apache를 열려면 mod_deflate를 사용하고, 콘텐츠를 먼저 버퍼에 넣으려면 ob_start를 엽니다.

3. 루프 도중이 아니라 루프 전에 최대 루프 수를 설정하십시오.

이것은 모든 바보가 이해하는 진실입니다.

4. 메모리를 해제하기 위해 변수, 특히 큰 배열을 삭제합니다.

PHP에서 배열과 객체가 많은 메모리를 차지합니다. 이는 PHP의 기본 zend 엔진으로 인해 발생합니다. /10, 즉 C 언어에서 100M 메모리 배열은 PHP에서 1G가 필요합니다.
특히 PHP를 백엔드 서버로 사용하는 시스템에서는 과도한 메모리 소모 문제가 자주 발생합니다.

5. __get, __set, __autoload와 같은 매직 메소드 사용을 피하세요(참고용

, 토론 대상).

__로 시작하는 함수는 특정 조건에서 사용되는 함수입니다. 일반적으로 다음과 같은 마법 함수가 있습니다.

__construct(), __destruct(), __get(), __set(), __unset(), __call(), __callStatic(), __sleep(), __wakeup(), __toString() , __set_state(), __clone(), __autoload()

실제로 __autoload가 클래스 이름을 실제 디스크 파일과 효율적으로 일치시킬 수 없는 경우(참고: 이는 파일 이름뿐만 아니라 실제 디스크 파일을 나타냄) 시스템은 파일이 존재하는지 여부에 대해 많은 판단을 내려야 하며(각 포함 경로에 포함된 경로에서 검색해야 함) 파일이 존재하는지 판단하려면 디스크 I/O 작업이 필요합니다. 우리 모두 알고 있듯이 디스크 I/O 작업은 다음과 같습니다. 매우 효율적입니다. 낮음으로 인해 자동 로드 메커니즘이 덜 효율적입니다.

따라서 시스템을 설계할 때 클래스 이름을 실제 디스크 파일에 매핑하기 위한 명확한 메커니즘을 정의해야 합니다. 이 규칙이 더 간단하고 명확할수록 자동 로드 메커니즘은 더 효율적입니다.

결론: 자동 로드 메커니즘은 본질적으로 비효율적이지 않습니다. 자동 로드 기능을 남용하고 잘못 설계된 자동 로드 기능만 있으면 효율성이 저하됩니다.

따라서 논의의 여지가 있는 __autoload 매직 방법을 사용하지 마십시오.

6.requiere_once()는 리소스를 더 많이 소모합니다.

requirere_once는 파일이 참조되었는지 여부를 확인해야 하기 때문에 최대한 활용해야 합니다. 피하기 위해 일반적으로 사용되는 require/include 메서드입니다.

7. 포함 및 요구 사항에 절대 경로를 사용하세요.

상대 경로가 포함된 경우 PHP는 파일을 찾기 위해 include_path를 탐색합니다.

절대 경로를 사용하면 이러한 문제를 피할 수 있으므로 운영 체제 경로를 해결하는 데 시간이 덜 걸립니다.

8. 스크립트가 실행될 때 시간을 가져와야 하는 경우 $_SERVER['REQUSET_TIME']이 time();

상상하는 것보다 낫습니다. 하나는 기성품으로 바로 사용할 수 있고, 다른 하나는 함수를 통해 얻은 결과가 필요합니다.

9. PHP의 내부 문자열 조작 기능을 사용할 수 있다면 정규 표현식 대신 이를 사용해 보십시오. 정규 표현식보다 효율성이 높기 때문입니다.

말할 필요도 없이 정규 표현식은 가장 많은 성능을 소모합니다.
혹시 놓친 유용한 기능이 있나요? 예: strpbrk() strncasecmp() strpos()/strrpos()/stripos()/strripos() 변환해야 할 것이 단일 문자뿐이라면
배열 대신 문자열을 사용하여 strtr을 수행하세요. :

<?php
$addr = strtr($addr, "abcd", "efgh"); // good
$addr = strtr($addr, array(&#39;a&#39; => &#39;e&#39;, )); // bad
?>

효율성 향상: 10배.

10.str_replace 문자 교체는 일반 교체 preg_replace보다 빠르지만 strtr은 str_replace보다 1/4 빠릅니다.

또한 교체가 없더라도 str_replace는 해당 매개변수에 대해 메모리를 할당하지 않습니다. . 매우 느리다! 해결 방법:
strpos를 사용하여 먼저 검색하여(매우 빠르게) 필요한 경우 다시 교체하십시오. 효율성: - 교체해야 하는 경우: 효율성은 거의 동일하며 차이는 약 0.1입니다. %.
교체가 필요하지 않은 경우: strpos가 200% 더 빠릅니다.

11. 매개변수가 문자열입니다

문자 대체 함수와 같이 함수가 배열과 단순 문자를 모두 매개변수로 허용할 수 있고 매개변수 목록이 너무 길지 않은 경우에는 다음과 같은 추가 대체 코드 작성을 고려할 수 있습니다. 각 패스 매개변수는 검색 및 대체 매개변수로 배열을 허용하는 것이 아니라 모두 하나의 문자입니다. 큰 것을 작게 만드세요, 1+1>2;

12 @를 사용하지 않는 것이 가장 좋습니다. 오류를 덮기 위해 @를 사용하면 스크립트의 실행 속도가 느려집니다.

@를 사용하면 실제로 많은 작업이 수반됩니다. 배경. @를 사용하는 것과 @를 사용하지 않는 것의 효율성 차이는 3배입니다. 특히 루프 5개 테스트에서는 error_reporting(0)을 사용하여 먼저 오류를 끈 다음 루프가 완료된 후 켜더라도 @를 사용하는 것보다 빠릅니다.

13.$row['id']는 $row[id]보다 7배 빠릅니다

배열 키에 따옴표를 추가하는 습관을 들이는 것이 좋습니다.

14 루프에서 함수를 사용하지 마세요

. 예를 들어($x =0; $x 8edb1792376d1de1570ff9f67ad2991eprop++)와 같은 객체 속성(클래스의 변수)을 만드는 것은 지역 변수보다 3배 느립니다.

19. 이미 정의된 지역 변수는 9~10배 느립니다

20. 어떤 함수에서도 사용되지 않는 전역 변수를 선언하면 성능이 저하됩니다(동일한 수의 지역 변수를 선언하면).

PHP는 이 전역 변수가 존재하는지 확인할 수 있습니다.

21. 메소드의 성능은 클래스에 정의된 메소드 수와 관련이 없습니다.

테스트된 클래스에 10개 이상의 메소드를 추가했기 때문입니다.

22. 하위 클래스의 메서드 성능이 기본 클래스의 성능보다 낫습니다.

23. 빈 함수 본문은 7 -8개의 $localvar++ 작업과 동일하지만 비슷한 메서드(클래스의 함수)는 약 15개의 $localvar++ 작업과 동일하게 실행됩니다.

24 문자열을 묶으려면 큰따옴표 대신 작은따옴표를 사용하세요. 그게 더 빠릅니다.

PHP는 큰따옴표로 묶인 문자열에서 변수를 검색하기 때문에 작은따옴표는 검색하지 않습니다.

PHP 엔진에서는 작은따옴표와 큰따옴표를 사용하여 문자열 변수를 캡슐화할 수 있지만 큰 차이가 있습니다! 큰따옴표로 묶인 문자열을 사용하면 PHP 엔진이 먼저 문자열의 내용을 읽고 그 안에 있는 변수를 찾은 다음 변수에 해당하는 값으로 변경하도록 지시합니다. 일반적으로 문자열에는 변수가 없으므로 큰따옴표를 사용하면 성능이 저하됩니다. 큰따옴표로 묶인 문자열 대신

문자열 연결을 사용하는 것이 더 좋습니다.


BAD:
$output = "This is a plain string";
GOOD:
$output = &#39;This is a plain string&#39;;
BAD: 
$type = "mixed";
$output = "This is a $type string";
GOOD:
$type = &#39;mixed&#39;;
$output = &#39;This is a &#39; . $type .&#39; string&#39;;

25 문자열을 반향할 때 점 연결선 대신 쉼표를 사용하는 것이 더 빠릅니다.

Echo는 여러 문자열을 매개변수로 사용할 수 있는 "함수"입니다. (번역 참고: PHP 매뉴얼에서는 echo가 실제 함수가 아닌 언어 구조라고 되어 있으므로 함수를 큰따옴표로 묶습니다.)

  例如echo $str1,$str2。

26.Apache解析一个PHP脚本的时间要比解析一个静态HTML页面慢2至10倍。

     尽量多用静态HTML页面,少用脚本。

28.尽量使用缓存,建议用memcached。

   高性能的分布式内存对象缓存系统,提高动态网络应用程序性能,减轻数据库的负担;

   也对运算码 (OP code)的缓存很有用,使得脚本不必为每个请求做重新编译。

29.使用ip2long()和long2ip()函数把IP地址转成整型存放进数据库而非字符型。

     这几乎能降低1/4的存储空间。同时可以很容易对地址进行排序和快速查找;

30.使用checkdnsrr()通过域名存在性来确认部分email地址的有效性

    这个内置函数能保证每一个的域名对应一个IP地址;

31.使用mysql_*的改良函数mysqli_*;

32.试着喜欢使用三元运算符(?:);

33.是否需要PEAR

在你想在彻底重做你的项目前,看看PEAR有没有你需要的。PEAR是个巨大的资源库,很多php开发者都知道;

35.使用error_reporting(0)函数来预防潜在的敏感信息显示给用户。

  理想的错误报告应该被完全禁用在php.ini文件里。可是如果你在用一个共享的虚拟主机,php.ini你不能修改,那么你最好添加error_reporting(0)函数,放在每个脚本文件的第一行(或用

require_once()来加载)这能有效的保护敏感的SQL查询和路径在出错时不被显示;

36.使用 gzcompress() 和gzuncompress()对容量大的字符串进行压缩(解压)在存进(取出)数据库时。

    这种内置的函数使用gzip算法能压缩到90%;

37.通过参数变量地址得引用来使一个函数有多个返回值。

   你可以在变量前加个“&”来表示按地址传递而非按值传递;

38. 完全理解魔术引用和SQL注入的危险。

    Fully understand “magic quotes” and the dangers of SQL injection. I’m hoping that most developers reading this are already familiar with SQL injection. However, I list it here because it’s absolutely critical to understand. If you’ve never heard the term before, spend the entire rest of the day googling and reading.

39.某些地方使用isset代替strlen

  当操作字符串并需要检验其长度是否满足某种要求时,你想当然地会使用strlen()函数。此函数执行起来相当快,因为它不做任何计算,只返回在zval 结构(C的内置数据结构,用于存储PHP变量)中存储的已知字符串长度。但是,由于strlen()是函数,多多少少会有些慢,因为函数调用会经过诸多步骤,如字母小写化(译注:指函数名小写化,PHP不区分函数名大小写)、哈希查找,会跟随被调用的函数一起执行。在某些情况下,你可以使用isset() 技巧加速执行你的代码。

(举例如下)if (strlen($foo) < 5) { echo “Foo is too short”
} (与下面的技巧做比较) if (!isset($foo{5})) { echo “Foo is too short”
}

调用isset()恰巧比strlen()快,因为与后者不同的是,isset()作为一种语言结构,意味着它的执行不需要函数查找和字母小写化。也就是说,实际上在检验字符串长度的顶层代码中你没有花太多开销。

40.使用++$i递增

When incrementing or decrementing the value of the variable $i++ happens to be a tad slower then ++$i. This is something PHP specific and does not apply to other languages, so don’t go modifying your C or Java code thinking it’ll suddenly become faster, it won’t. ++$i happens to be faster in PHP because instead of 4 opcodes used for $i++ you only need 3. Post incrementation actually causes in the creation of a temporary var that is then incremented. While preincrementation increases the original value directly. This is one of the optimization that opcode optimized like Zend’s PHP optimizer. It is a still a good idea to keep in mind since not all opcode optimizers perform this optimization and there are plenty of ISPs and servers running without an opcode optimizer.

   当执行变量$i的递增或递减时,$i++会比++$i慢一些。这种差异是PHP特有的,并不适用于其他语言,所以请不要修改你的C或Java代码并指望它们能立即变快,没用的。++$i更快是因为它只需要3条指令(opcodes),$i++则需要4条指令。后置递增实际上会产生一个临时变量,这个临时变量随后被递增。而前置递增直接在原值上递增。这是最优化处理的一种,正如Zend的PHP优化器所作的那样。牢记这个优化处理不失为一个好主意,因为并不是所有的指令优化器都会做同样的优化处理,并且存在大量没有装配指令优化器的互联网服务
提供商(ISPs)和服务器。

40. 不要随便就复制变量

有时候为了使 PHP 代码更加整洁,一些 PHP 新手(包括我)会把预定义好的变量复制到一个名字更简短的变量中,其实这样做的结果是增加了一倍的内存消耗,只会使程序更加慢。试想一下,在下面的例子中,如果用户恶意插入 512KB 字节的文字到文本输入框中,这样就会导致 1MB 的内存被消耗!

BAD:
$description = $_POST[&#39;description&#39;];
echo $description;
GOOD:
echo $_POST[&#39;description&#39;];

41 使用选择分支语句

     switch case好于使用多个if,else if语句,并且代码更加容易阅读和维护。

42.在可以用file_get_contents替代file、fopen、feof、fgets

    在可以用file_get_contents替代file、fopen、feof、fgets等系列方法的情况下,尽量用file_get_contents,因为他的效率高得多!但是要注意file_get_contents在打开一个URL文件时候的PHP版本问题;

43.尽量的少进行文件操作,虽然PHP的文件操作效率也不低的;

44.优化Select SQL语句,在可能的情况下尽量少的进行Insert、Update操作(在update上,我被恶批过);

45.尽可能的使用PHP内部函数

46.循环内部不要声明变量,尤其是大变量:对象

   (这好像不只是PHP里面要注意的问题吧?);

47.多维数组尽量不要循环嵌套赋值;

48.foreach效率更高,尽量用foreach代替while和for循环;

50.对global变量,应该用完就unset()掉;

51 并不是事必面向对象(OOP),面向对象往往开销很大,每个方法和对象调用都会消耗很多内存。

52 不要把方法细分得过多,仔细想想你真正打算重用的是哪些代码?

53 如果在代码中存在大量耗时的函数,你可以考虑用C扩展的方式实现它们。

54、压缩输出:打开apache的mod_deflate模块,可以提高网页的浏览速度。

   (提到过echo 大变量的问题)

55、数据库连接当使用完毕时应关掉,不要用长连接。

56、split比exploade快

split()
0.001813 - 0.002271 seconds (avg 0.002042 seconds)
explode()
0.001678 - 0.003626 seconds (avg 0.002652 seconds)
Split can take regular expressions as delimiters, and runs faster too. ~23% on average.

以上都是关于php代码的优化,下面是从整体结构方面优化PHP性能:

整体结构方面优化PHP性能

1.将PHP升级到最新版

  提高性能的最简单的方式是不断升级、更新PHP版本。

2.使用分析器

  网站运行缓慢的原因颇多,Web应用程序极其复杂,让人扑朔迷离。而一种可能性在于PHP代码本身。这个分析器可以帮助你快速找出造成瓶颈的代码,提高网站运行的总体性能。

  Xdebug PHP extension提供了强大的功能,可以用来调试,也可以用来分析代码。方便开发人员直接跟踪脚本的执行,实时查看综合数据。还可以将这个数据导入到可视化的工具 KCachegrind中。

3.检错报告

  PHP支持强大的检错功能,方便你实时检查错误,从比较重要的错误到相对小的运行提示。总共支持13种独立的报告级别,你可以根据这些级别灵活匹配,生成用户自定义的检测报告。

4.利用PHP的扩展

 모든 사람들은 항상 PHP 콘텐츠가 너무 복잡하다고 불평해 왔습니다. 최근 몇 년 동안 개발자들은 프로젝트에서 일부 중복 기능을 제거하기 위해 이에 상응하는 노력을 기울였습니다. 그럼에도 불구하고 사용 가능한 라이브러리 및 기타 확장 기능의 수는 인상적입니다. 일부 개발자는 자체 확장 기능 구현을 고려하기 시작했습니다.

5.PHP 캐시, PHP 가속기 사용: APC

일반적인 상황에서 PHP 스크립트는 PHP 엔진에 의해 컴파일 및 실행되며 opcode라고도 하는 기계어로 변환됩니다. PHP 스크립트가 반복적으로 컴파일되어 동일한 결과를 얻는다면 컴파일 프로세스를 완전히 건너뛰는 것이 어떨까요?

PHP 스크립트의 컴파일된 기계어 코드를 캐시하여 코드가 필요에 따라 컴파일 지루한 컴파일 과정을 거치지 않고 즉시 실행합니다.

PHP 개발자를 위해 현재 두 가지 캐싱 솔루션을 사용할 수 있습니다. 하나는 PEAR를 통해 설치할 수 있는 오픈 소스 가속기인 APC(대체 PHP 캐시, 선택적 PHP 캐시)입니다. 또 다른 인기 있는 솔루션은 Opcode 캐싱 기술을 제공할 뿐만 아니라 해당 페이지에 대한 캐싱 도구도 제공하는 Zend Server입니다.

6. 메모리 캐시

  PHP는 일반적으로 검색 및 데이터 분석에 중요한 역할을 하며 이러한 작업은 성능 저하를 유발할 수 있습니다. 실제로 일부 작업은 완전히 불필요하며, 특히 일반적으로 사용되는 일부 정적 데이터를 데이터베이스에서 반복적으로 검색하는 작업은 더욱 그렇습니다. 단기적으로는 Memcached 확장을 사용하여 데이터를 캐시하는 것을 고려할 수 있습니다. Memcached의 확장 캐시는 libMemcached 라이브러리와 함께 작동하여 RAM에 데이터를 캐시하고 사용자가 캐시 기간을 정의할 수 있도록 하여 사용자 정보의 실시간 업데이트를 보장합니다.

7.Content Compression:

거의 모든 브라우저는 Gzip 압축 방법을 지원하지만 Gzip은 CPU 계산을 약 10% 증가시키면서 출력을 80%까지 줄일 수 있습니다. 그러나 당신이 얻는 것은 점유된 대역폭이 줄어들 뿐만 아니라 페이지 로딩 속도가 빨라져 PHP 사이트의 성능이 최적화된다는 것입니다.
PHP.ini에서 켤 수 있습니다.
zlib.output_compression = On
zlib.output_compression_level = (레벨) (레벨은 1-9 사이의 숫자일 수 있으며 사이트에 적합하도록 다른 숫자를 설정할 수 있습니다.)
Apache를 사용하는 경우 고도로 사용자 정의 가능한 mod_gzip 모듈을 활성화할 수도 있습니다.

8. 서버 캐시:

주로 웹 리버스 프록시의 정적 서버 nginx 및 squid와 apache2의 mod_proxy 및 mod_cache 모듈을 기반으로 합니다.

9 데이터베이스 최적화: 데이터베이스 캐시 등. 데이터베이스 캐싱을 구성하여 QueryCache 캐시가 켜져 있는 경우 쿼리가 이전과 동일한 쿼리를 수신하면 서버는 마지막 쿼리를 다시 분석하고 실행하는 대신 쿼리 캐시에서 결과를 가져옵니다

​ 그리고 데이터 저장 절차, 커넥션 풀 기술 등


관련 권장 사항:

PHP 성능 최적화 팁 공유

PHP 성능 최적화의 자세한 예

5가지 PHP 성능 최적화 팁

위 내용은 PHP 성능 최적화 예제 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.