目錄
您可能感兴趣的文章:
首頁 後端開發 php教程 PHP中你可能忽略的效能最佳化利器:生成器的相關內容

PHP中你可能忽略的效能最佳化利器:生成器的相關內容

Jul 06, 2018 pm 05:51 PM
php效能優化 php網站效能優化

效能最佳化是我們開發中不可或缺的一部分,以下這篇文章主要給大家介紹了關於PHP中你可能忽略的效能最佳化利器:產生器的相關資料,文中透過範例程式碼介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

如果是做Python或是其他語言的小夥伴,對於生成器應該不陌生。但很多PHP開發者或許都不知道生成器這個功能,可能是因為生成器是PHP 5.5.0才引進的功能,也可以是生成器作用不是很明顯。但是,生成器功能的確非常有用。

什麼情況之下,會遇到PHP效能問題?

1:PHP語法使用不恰當。

2:使用PHP語言做了它不擅長的事。

3:使用PHP語言連線的服務不給力。

4:PHP本身的短板(PHP本身也做不了的事情)。

5:我們也不知道的問題? (去探索、分析找到解決方法,提升開發境界)。

優點

直接講概念估計你聽完還是一頭霧水,所以我們先來說說優點,也許能勾起你的興趣。那麼生成器有哪些優點,如下:

  • 生成器會對PHP應用的效能有非常大的影響

  • PHP程式碼執行時節省大量的記憶體

  • 比較適合計算大量的資料

那麼,這些神奇的功能究竟是如何做到的呢?我們先來舉個例子。

概念引入

首先,放下生成器概念的包袱,來看一個簡單的PHP函數:

function createRange($number){
 $data = [];
 for($i=0;$i<$number;$i++){
  $data[] = time();
 }
 return $data;
}
登入後複製

這是一個非常常見的PHP函數,我們在處理一些陣列的時候常常會使用。這裡的程式碼也非常簡單:

  • 我們建立一個函數。

  • 函數內包含一個for循環,我們循環的把當前時間放到$data裡面

  • for循環執行完畢,把$data返回出去。

下面沒完,我們繼續。我們再寫一個函數,把這個函數的回傳值循環印出來:

$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
 sleep(1);//这里停顿1秒,我们后续有用
 echo $value.&#39;<br />&#39;;
}
登入後複製

我們在瀏覽器裡面看一下運行結果:

這裡非常完美,沒有任何問題。 (當然sleep(1)效果你們看不出來)

思考一個問題

我們注意到,在呼叫函數createRange的時候給$number的傳值是10,一個很小的數字。假設,現在傳遞一個值10000000(1000萬)。

那麼,在函數createRange裡面,for迴圈就需要執行1000萬次。且有1000萬個值被放到$data裡面,而$data數組在是被放在記憶體內。所以,在呼叫函數時候會佔用大量記憶體。

這裡,生成器就可以大顯身手了。

建立生成器

我們直接修改程式碼,你們注意觀察:

function createRange($number){
 for($i=0;$i<$number;$i++){
  yield time();
 }
}
登入後複製

看下這段和剛剛很像的程式碼,我們刪除了數組$data,而且也沒有回傳任何內容,而是在time()之前使用了一個關鍵字yield

#使用生成器

我們再執行第二段程式碼:

$result = createRange(10); / / 這裡呼叫上面我們所建立的函數
foreach($result as $value){
    sleep(1);
    echo $value.'
';
}


#我們奇蹟般的發現了,輸出的值和第一次沒有使用生成器的不一樣。這裡的值(時間戳記)中間間隔了1秒。

這裡的間隔一秒鐘其實就是sleep(1)造成的後果。但為什麼第一次沒有間隔呢?那是因為:

  • 未使用生成器時:createRange函數內的for循環結果很快就會放到$data中,並且立即傳回。所以,foreach循環的是一個固定的陣列。

  • 使用生成器時:createRange的值不是一次性快速生成,而是依賴foreach循環。 foreach迴圈一次,fo​​r執行一次。

到這裡,你應該對生成器有點兒頭緒。

深入理解生成器

#程式碼剖析

#下面我們來對於剛剛的程式碼進行剖析。

function createRange($number){
 for($i=0;$i<$number;$i++){
  yield time();
 }
}
$result = createRange(10); // 这里调用上面我们创建的函数
foreach($result as $value){
 sleep(1);
 echo $value.'
'; }
登入後複製

我們來還原一下程式碼執行過程。

  • 首先调用createRange函数,传入参数10,但是for值执行了一次然后停止了,并且告诉foreach第一次循环可以用的值。

  • foreach开始对$result循环,进来首先sleep(1),然后开始使用for给的一个值执行输出。

  • foreach准备第二次循环,开始第二次循环之前,它向for循环又请求了一次。

  • for循环于是又执行了一次,将生成的时间戳告诉foreach.

  • foreach拿到第二个值,并且输出。由于foreach中sleep(1),所以,for循环延迟了1秒生成当前时间

所以,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。

无论开始传入的$number有多大,由于并不会立即生成所有结果集,所以内存始终是一条循环的值。

概念理解

到这里,你应该已经大概理解什么是生成器了。下面我们来说下生成器原理。

首先明确一个概念:生成器yield关键字不是返回值,他的专业术语叫产出值,只是生成一个值

那么代码中foreach循环的是什么?其实是PHP在使用生成器的时候,会返回一个Generator类的对象。foreach可以对该对象进行迭代,每一次迭代,PHP会通过Generator实例计算出下一次需要迭代的值。这样foreach就知道下一次需要迭代的值了。

而且,在运行中for循环执行后,会立即停止。等待foreach下次循环时候再次和for索要下次的值的时候,for循环才会再执行一次,然后立即再次停止。直到不满足条件不执行结束。

实际开发应用

很多PHP开发者不了解生成器,其实主要是不了解应用领域。那么,生成器在实际开发中有哪些应用?

读取超大文件

PHP开发很多时候都要读取大文件,比如csv文件、text文件,或者一些日志文件。这些文件如果很大,比如5个G。这时,直接一次性把所有的内容读取到内存中计算不太现实。

这里生成器就可以派上用场啦。简单看个例子:读取text文件

我们创建一个text文本文档,并在其中输入几行文字,示范读取。

<?php
header("content-type:text/html;charset=utf-8");
function readTxt()
{
 # code...
 $handle = fopen("./test.txt", &#39;rb&#39;);

 while (feof($handle)===false) {
  # code...
  yield fgets($handle);
 }

 fclose($handle);
}

foreach (readTxt() as $key => $value) {
 # code...
 echo $value.&#39;<br />&#39;;
}
登入後複製


通过上图的输出结果我们可以看出代码完全正常。

但是,背后的代码执行规则却一点儿也不一样。使用生成器读取文件,第一次读取了第一行,第二次读取了第二行,以此类推,每次被加载到内存中的文字只有一行,大大的减小了内存的使用。

这样,即使读取上G的文本也不用担心,完全可以像读取很小文件一样编写代码。

总结

您可能感兴趣的文章:

Laravel框架中composer自动加载的实现详解

PHP服务端环境搭建的图文教程

php实现希尔排序算法的方法讲解

以上是PHP中你可能忽略的效能最佳化利器:生成器的相關內容的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

使用PHP開發實現百度文心一言API介面的效能最佳化技巧 使用PHP開發實現百度文心一言API介面的效能最佳化技巧 Aug 26, 2023 pm 10:39 PM

使用PHP開發實現百度文心一言API介面的效能優化技巧隨著網路的普及,越來越多的開發者使用第三方API介面來獲取數據,以豐富自己的應用內容。百度文心一言API接口是廣受歡迎的一種資料接口,它可以傳回一句隨機的勵志、哲理或溫馨的語句,可以用於美化程式介面、增加使用者體驗等面向。然而,在使用百度文心一言API介面時,我們也面臨一些效能上的考量。 API呼叫的速度

如何透過PHP程式碼規範規範效能最佳化 如何透過PHP程式碼規範規範效能最佳化 Aug 11, 2023 pm 03:51 PM

如何通过PHP代码规范规范性能优化引言:随着互联网的迅速发展,越来越多的网站和应用程序基于PHP语言开发。在PHP开发过程中,性能优化是一个至关重要的方面。一个高性能的PHP代码可以显著提高网站的响应速度和用户体验。本文将探讨如何通过PHP代码规范来规范性能优化,并提供一些实际的代码示例供参考。一、减少数据库查询在开发过程中,频繁的数据库查询是一个常见的性能

如何使用 PHP 優化網站效能和載入速度 如何使用 PHP 優化網站效能和載入速度 Sep 12, 2023 am 10:13 AM

如何使用PHP優化網站效能和載入速度隨著網路的快速發展,網站的效能和載入速度越來越受到人們的關注。而作為一種廣泛使用的伺服器端腳本語言,PHP在優化網站效能和載入速度方面具有重要作用。本文將介紹一些使用PHP的技巧和方法,以提高網站的效能和載入速度。使用快取機制快取是提高網站效能的有效方法。 PHP提供了多種快取機制,如檔案快取、記憶體快取和數

PHP 7效能最佳化技巧:如何使用isset函數判斷變數是否已聲明 PHP 7效能最佳化技巧:如何使用isset函數判斷變數是否已聲明 Aug 01, 2023 am 08:27 AM

PHP7效能最佳化技巧:如何使用isset函數判斷變數是否已宣告引言:在PHP開發中,我們經常需要判斷一個變數是否已經被宣告。這在一些情況下尤其重要,例如在使用未宣告的變數時會產生錯誤。在PHP7中,出於效能最佳化的考慮,我們應該盡量使用isset函數來判斷變數是否已經被聲明,而不是直接使用諸如empty、is_null等函數。為什麼要使用isset:在PHP

如何使用PHP進行效能最佳化和調優 如何使用PHP進行效能最佳化和調優 Aug 02, 2023 pm 09:40 PM

如何使用PHP進行效能最佳化和調優在開發Web應用的過程中,效能最佳化和調優是不可忽視的重要任務。 PHP作為一種流行的伺服器端腳本語言,也有一些能夠提升效能的技巧和工具。本文將介紹一些常見的PHP效能最佳化和調優方法,並提供範例程式碼以幫助讀者更好地理解。使用快取快取是提高Web應用效能的重要手段之一。可以透過使用快取來減少對資料庫的訪問,減少IO操作以提高效能。使

如何提高PHP在高並發環境下的效能 如何提高PHP在高並發環境下的效能 Aug 11, 2023 pm 07:30 PM

如何提高PHP在高並發環境下的效能摘要:隨著網路技術的發展,越來越多的網站和應用程式需要處理大量的並發請求。而對於使用PHP作為後端開發語言的系統來說,在高並發環境下的效能最佳化顯得特別重要。本文將介紹一些提高PHP在高並發環境下效能的方法,包括程式碼最佳化、快取使用和資料庫最佳化。一.程式碼最佳化選擇合適的PHP框架:選擇合適的PHP框架可以提高系統的開發效率和效能

PHP商品庫存管理系統的效能最佳化指南 PHP商品庫存管理系統的效能最佳化指南 Aug 17, 2023 am 08:29 AM

PHP商品庫存管理系統的效能最佳化指南隨著電商產業不斷發展壯大,面對龐大的商品庫存資料和日益增長的使用者存取量,對於商品庫存管理系統的效能要求也越來越高。在PHP開發中,如何對商品庫存管理系統進行最佳化,提升系統的效能與反應速度,是一個很重要的問題。本文將介紹一些常見的效能最佳化技巧,並給出相應的程式碼範例,幫助開發者更好地理解和應用。資料庫效能優化1.1.使用索引

優化你的程式碼:PHP高效能技巧 優化你的程式碼:PHP高效能技巧 Jun 05, 2023 am 08:21 AM

在實際開發中,為了讓網站或應用程式達到更好的效能和更高的可擴充性,PHP程式碼的最佳化是非常重要的一步。以下是一些PHP高效能技巧,幫助你的程式碼更快運作。一、最小化函數呼叫和變數1.1函數呼叫函數呼叫對於PHP程式碼的效能影響非常大,因為每個函數都需要在記憶體中分配空間。在編寫PHP程式碼時應盡量避免過多的函數調用,可以使用內聯函數或自訂函數來替代。 1.2變數

See all articles