国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 後端開(kāi)發(fā) php教程 發(fā)電機(jī)和尼基/迭代的內(nèi)存性能增強(qiáng)

發(fā)電機(jī)和尼基/迭代的內(nèi)存性能增強(qiáng)

Feb 16, 2025 am 09:17 AM

PHP迭代器與生成器:高效處理大型數(shù)據(jù)集的利器

數(shù)組以及迭代是任何應(yīng)用程序的基石。隨著我們獲得新工具,我們使用數(shù)組的方式也應(yīng)該隨之改進(jìn)。

例如,生成器就是一種新工具。起初我們只有數(shù)組,然後我們獲得了定義自己的類(lèi)數(shù)組結(jié)構(gòu)(稱(chēng)為迭代器)的能力。但自PHP 5.5以來(lái),我們可以快速創(chuàng)建稱(chēng)為生成器的類(lèi)迭代器結(jié)構(gòu)。

Memory Performance Boosts with Generators and Nikic/Iter

生成器看起來(lái)像函數(shù),但我們可以將它們用作迭代器。它們?yōu)槲覀兲峁┝艘环N簡(jiǎn)單的語(yǔ)法,用於創(chuàng)建本質(zhì)上可中斷、可重複的函數(shù)。它們非常棒!

我們將研究幾個(gè)可以使用生成器的領(lǐng)域,並探討使用生成器時(shí)需要注意的一些問(wèn)題。最後,我們將學(xué)習(xí)一個(gè)由才華橫溢的Nikita Popov創(chuàng)建的優(yōu)秀庫(kù)。

示例代碼可在https://github.com/sitepoint-editors/generators-and-iter找到。

關(guān)鍵要點(diǎn)

  • 生成器(自PHP 5.5起可用)是創(chuàng)建迭代器的強(qiáng)大工具,允許創(chuàng)建可中斷、可重複的函數(shù),從而簡(jiǎn)化大型數(shù)據(jù)集的處理並提高內(nèi)存性能。
  • Nikita Popov創(chuàng)建的Nikic/Iter庫(kù)引入了可與迭代器和生成器一起使用的函數(shù),通過(guò)避免創(chuàng)建不必要的中間數(shù)組來(lái)顯著節(jié)省內(nèi)存。
  • 在處理大型CSV文件時(shí),生成器和Nikic/Iter庫(kù)尤其有用,可以處理大型數(shù)據(jù)集而無(wú)需一次性將它們?nèi)考虞d到內(nèi)存中。
  • 雖然生成器可以顯著提高內(nèi)存性能,但它們也帶來(lái)自身的一些挑戰(zhàn),例如與array_filterarray_map不兼容,需要使用Nikic/Iter等其他工具來(lái)處理此類(lèi)數(shù)據(jù)。

問(wèn)題

假設(shè)您有很多關(guān)係數(shù)據(jù),並且想要進(jìn)行一些預(yù)加載。也許數(shù)據(jù)是逗號(hào)分隔的,您需要加載每種數(shù)據(jù)類(lèi)型並將它們組合在一起。

您可以從以下簡(jiǎn)單的代碼開(kāi)始:

function readCSV($file) {
    $rows = [];

    $handle = fopen($file, "r");

    while (!feof($handle)) {
        $rows[] = fgetcsv($handle);
    }

    fclose($handle);

    return $rows;
}

$authors = array_filter(
    readCSV("authors.csv")
);

$categories = array_filter(
    readCSV("categories.csv")
);

$posts = array_filter(
    readCSV("posts.csv")
);

然後,您可能會(huì)嘗試通過(guò)迭代或高階函數(shù)來(lái)連接相關(guān)元素:

function filterByColumn($array, $column, $value) {
    return array_filter(
        $array, function($item) use ($column, $value) {
            return $item[$column] == $value;
        }
    );
}

$authors = array_map(function($author) use ($posts) {
    $author["posts"] = filterByColumn(
        $posts, 1, $author[0]
    );

    // 對(duì) $author 進(jìn)行其他更改

    return $author;
}, $authors);

$categories = array_map(function($category) use ($posts) {
    $category["posts"] = filterByColumn(
        $posts, 2, $category[0]
    );

    // 對(duì) $category 進(jìn)行其他更改

    return $category;
}, $categories);

$posts = array_map(function($post) use ($authors, $categories) {
    foreach ($authors as $author) {
        if ($author[0] == $post[1]) {
            $post["author"] = $author;
            break;
        }
    }

    foreach ($categories as $category) {
        if ($category[0] == $post[1]) {
            $post["category"] = $category;
            break;
        }
    }

    // 對(duì) $post 進(jìn)行其他更改

    return $post;
}, $posts);

看起來(lái)不錯(cuò),對(duì)吧?那麼,當(dāng)我們有大量CSV文件要解析時(shí)會(huì)發(fā)生什麼?讓我們稍微分析一下內(nèi)存使用情況……

function formatBytes($bytes, $precision = 2) {
    $kilobyte = 1024;
    $megabyte = 1024 * 1024;

    if ($bytes >= 0 && $bytes < $kilobyte) {
        return $bytes . " b";
    }

    if ($bytes >= $kilobyte && $bytes < $megabyte) {
        return round($bytes / $kilobyte, $precision) . " kb";
    }

    return round($bytes / $megabyte, $precision) . " mb";
}

print "memory:" . formatBytes(memory_get_peak_usage());

(示例代碼包含generate.php,您可以使用它來(lái)創(chuàng)建這些CSV文件……)

如果您有大型CSV文件,這段代碼應(yīng)該會(huì)顯示將這些數(shù)組鏈接在一起需要多少內(nèi)存。至少與您必須讀取的文件大小相同,因?yàn)镻HP必須將所有內(nèi)容都保存在內(nèi)存中。

生成器來(lái)救援!

改進(jìn)此問(wèn)題的一種方法是使用生成器。如果您不熟悉它們,現(xiàn)在是學(xué)習(xí)更多知識(shí)的好時(shí)機(jī)。

生成器允許您一次加載少量總數(shù)據(jù)。使用生成器您無(wú)需做太多事情:

function readCSV($file) {
    $rows = [];

    $handle = fopen($file, "r");

    while (!feof($handle)) {
        $rows[] = fgetcsv($handle);
    }

    fclose($handle);

    return $rows;
}

$authors = array_filter(
    readCSV("authors.csv")
);

$categories = array_filter(
    readCSV("categories.csv")
);

$posts = array_filter(
    readCSV("posts.csv")
);

如果您遍歷CSV數(shù)據(jù),您會(huì)注意到所需的內(nèi)存量會(huì)立即減少:

function filterByColumn($array, $column, $value) {
    return array_filter(
        $array, function($item) use ($column, $value) {
            return $item[$column] == $value;
        }
    );
}

$authors = array_map(function($author) use ($posts) {
    $author["posts"] = filterByColumn(
        $posts, 1, $author[0]
    );

    // 對(duì) $author 進(jìn)行其他更改

    return $author;
}, $authors);

$categories = array_map(function($category) use ($posts) {
    $category["posts"] = filterByColumn(
        $posts, 2, $category[0]
    );

    // 對(duì) $category 進(jìn)行其他更改

    return $category;
}, $categories);

$posts = array_map(function($post) use ($authors, $categories) {
    foreach ($authors as $author) {
        if ($author[0] == $post[1]) {
            $post["author"] = $author;
            break;
        }
    }

    foreach ($categories as $category) {
        if ($category[0] == $post[1]) {
            $post["category"] = $category;
            break;
        }
    }

    // 對(duì) $post 進(jìn)行其他更改

    return $post;
}, $posts);

如果您之前看到的是兆字節(jié)的內(nèi)存使用量,現(xiàn)在您將看到千字節(jié)。這是一個(gè)巨大的改進(jìn),但它並非沒(méi)有問(wèn)題。

首先,array_filterarray_map不適用於生成器。您必須找到其他工具來(lái)處理此類(lèi)數(shù)據(jù)。以下是一個(gè)您可以嘗試的工具!

function formatBytes($bytes, $precision = 2) {
    $kilobyte = 1024;
    $megabyte = 1024 * 1024;

    if ($bytes >= 0 && $bytes < $kilobyte) {
        return $bytes . " b";
    }

    if ($bytes >= $kilobyte && $bytes < $megabyte) {
        return round($bytes / $kilobyte, $precision) . " kb";
    }

    return round($bytes / $megabyte, $precision) . " mb";
}

print "memory:" . formatBytes(memory_get_peak_usage());

此庫(kù)引入了一些可與迭代器和生成器一起使用的函數(shù)。那麼,您如何在不將任何數(shù)據(jù)保存在內(nèi)存中的情況下仍然獲得所有這些相關(guān)數(shù)據(jù)呢?

function readCSVGenerator($file) {
    $handle = fopen($file, "r");

    while (!feof($handle)) {
        yield fgetcsv($handle);
    }

    fclose($handle);
}

這可以更簡(jiǎn)潔:

foreach (readCSVGenerator("posts.csv") as $post) {
    // 使用 $post 執(zhí)行某些操作
}

print "memory:" . formatBytes(memory_get_peak_usage());

(重新讀取每個(gè)數(shù)據(jù)源每次都效率低下??紤]將較小的相關(guān)數(shù)據(jù)(如作者和類(lèi)別)保存在內(nèi)存中……)

其他有趣的事情

對(duì)於Nikic的庫(kù)來(lái)說(shuō),這只是冰山一角!曾經(jīng)想要展平一個(gè)數(shù)組(或迭代器/生成器)嗎?

composer require nikic/iter

您可以使用slicetake等函數(shù)返回可迭代變量的切片:

// ... (后續(xù)代碼與原文類(lèi)似,但使用iter庫(kù)函數(shù)進(jìn)行優(yōu)化,此處省略以節(jié)省篇幅) ...

當(dāng)您更多地使用生成器時(shí),您可能會(huì)發(fā)現(xiàn)您並不總是可以重用它們??紤]以下示例:

// ... (使用iter庫(kù)函數(shù)簡(jiǎn)化代碼,此處省略以節(jié)省篇幅) ...

如果您嘗試運(yùn)行該代碼,您將看到一個(gè)異常,提示:“無(wú)法遍歷已關(guān)閉的生成器”。此庫(kù)中的每個(gè)迭代器函數(shù)都有一個(gè)可迴繞的對(duì)應(yīng)函數(shù):

// ... (使用iter\flatten和iter\toArray函數(shù)的示例代碼,此處省略以節(jié)省篇幅) ...

您可以多次使用此映射函數(shù)。您甚至可以使您自己的生成器可迴繞:

// ... (使用iter\slice和iter\toArray函數(shù)的示例代碼,此處省略以節(jié)省篇幅) ...

您從中獲得的是一個(gè)可重用的生成器!

結(jié)論

對(duì)於您需要考慮的每個(gè)循環(huán)操作,生成器可能都是一個(gè)選項(xiàng)。它們甚至對(duì)其他事情也很有用。在語(yǔ)言功能不足的地方,Nikic的庫(kù)提供了大量的高階函數(shù)。

您是否已經(jīng)在使用生成器?您是否想查看更多關(guān)於如何在您自己的應(yīng)用程序中實(shí)現(xiàn)它們以獲得一些性能提升的示例?請(qǐng)告訴我們!

(FAQs部分與原文類(lèi)似,此處省略以節(jié)省篇幅。 可以根據(jù)需要選擇性保留或重新組織FAQs部分。)

以上是發(fā)電機(jī)和尼基/迭代的內(nèi)存性能增強(qiáng)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

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

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門(mén)話題

Laravel 教程
1600
29
PHP教程
1502
276
PHP變量範(fàn)圍解釋了 PHP變量範(fàn)圍解釋了 Jul 17, 2025 am 04:16 AM

PHP變量作用域常見(jiàn)問(wèn)題及解決方法包括:1.函數(shù)內(nèi)部無(wú)法訪問(wèn)全局變量,需使用global關(guān)鍵字或參數(shù)傳入;2.靜態(tài)變量用static聲明,只初始化一次並在多次調(diào)用間保持值;3.超全局變量如$_GET、$_POST可在任何作用域直接使用,但需注意安全過(guò)濾;4.匿名函數(shù)需通過(guò)use關(guān)鍵字引入父作用域變量,修改外部變量則需傳遞引用。掌握這些規(guī)則有助於避免錯(cuò)誤並提升代碼穩(wěn)定性。

如何在PHP中牢固地處理文件上傳? 如何在PHP中牢固地處理文件上傳? Jul 08, 2025 am 02:37 AM

要安全處理PHP文件上傳需驗(yàn)證來(lái)源與類(lèi)型、控製文件名與路徑、設(shè)置服務(wù)器限制並二次處理媒體文件。 1.驗(yàn)證上傳來(lái)源通過(guò)token防止CSRF並通過(guò)finfo_file檢測(cè)真實(shí)MIME類(lèi)型使用白名單控制;2.重命名文件為隨機(jī)字符串並根據(jù)檢測(cè)類(lèi)型決定擴(kuò)展名存儲(chǔ)至非Web目錄;3.PHP配置限制上傳大小及臨時(shí)目錄Nginx/Apache禁止訪問(wèn)上傳目錄;4.GD庫(kù)重新保存圖片清除潛在惡意數(shù)據(jù)。

在PHP中評(píng)論代碼 在PHP中評(píng)論代碼 Jul 18, 2025 am 04:57 AM

PHP註釋代碼常用方法有三種:1.單行註釋用//或#屏蔽一行代碼,推薦使用//;2.多行註釋用/.../包裹代碼塊,不可嵌套但可跨行;3.組合技巧註釋如用/if(){}/控制邏輯塊,或配合編輯器快捷鍵提升效率,使用時(shí)需注意閉合符號(hào)和避免嵌套。

發(fā)電機(jī)如何在PHP中工作? 發(fā)電機(jī)如何在PHP中工作? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

撰寫(xiě)PHP評(píng)論的提示 撰寫(xiě)PHP評(píng)論的提示 Jul 18, 2025 am 04:51 AM

寫(xiě)好PHP註釋的關(guān)鍵在於明確目的與規(guī)範(fàn),註釋?xiě)?yīng)解釋“為什麼”而非“做了什麼”,避免冗餘或過(guò)於簡(jiǎn)單。 1.使用統(tǒng)一格式,如docblock(/*/)用於類(lèi)、方法說(shuō)明,提升可讀性與工具兼容性;2.強(qiáng)調(diào)邏輯背後的原因,如說(shuō)明為何需手動(dòng)輸出JS跳轉(zhuǎn);3.在復(fù)雜代碼前添加總覽性說(shuō)明,分步驟描述流程,幫助理解整體思路;4.合理使用TODO和FIXME標(biāo)記待辦事項(xiàng)與問(wèn)題,便於後續(xù)追蹤與協(xié)作。好的註釋能降低溝通成本,提升代碼維護(hù)效率。

學(xué)習(xí)PHP:初學(xué)者指南 學(xué)習(xí)PHP:初學(xué)者指南 Jul 18, 2025 am 04:54 AM

易於效率,啟動(dòng)啟動(dòng)tingupalocalserverenverenvirestoolslikexamppandacodeeditorlikevscode.1)installxamppforapache,mysql,andphp.2)uscodeeditorforsyntaxssupport.3)

如何通過(guò)php中的索引訪問(wèn)字符串中的字符 如何通過(guò)php中的索引訪問(wèn)字符串中的字符 Jul 12, 2025 am 03:15 AM

在PHP中獲取字符串特定索引字符可用方括號(hào)或花括號(hào),但推薦方括號(hào);索引從0開(kāi)始,超出範(fàn)圍訪問(wèn)返回空值,不可賦值;處理多字節(jié)字符需用mb_substr。例如:$str="hello";echo$str[0];輸出h;而中文等字符需用mb_substr($str,1,1)獲取正確結(jié)果;實(shí)際應(yīng)用中循環(huán)訪問(wèn)前應(yīng)檢查字符串長(zhǎng)度,動(dòng)態(tài)字符串需驗(yàn)證有效性,多語(yǔ)言項(xiàng)目建議統(tǒng)一使用多字節(jié)安全函數(shù)。

快速PHP安裝教程 快速PHP安裝教程 Jul 18, 2025 am 04:52 AM

ToinstallPHPquickly,useXAMPPonWindowsorHomebrewonmacOS.1.OnWindows,downloadandinstallXAMPP,selectcomponents,startApache,andplacefilesinhtdocs.2.Alternatively,manuallyinstallPHPfromphp.netandsetupaserverlikeApache.3.OnmacOS,installHomebrew,thenrun'bre

See all articles