Maison  >  Article  >  développement back-end  >  PHP trouve un ensemble de différences et des débordements de mémoire dans un grand tableau

PHP trouve un ensemble de différences et des débordements de mémoire dans un grand tableau

王林
王林original
2023-05-22 19:27:06451parcourir

Dans le développement PHP, il est facile de rencontrer des problèmes de mémoire lorsqu'il s'agit de grands tableaux. Cet article explique comment utiliser l'algorithme array_diff pour résoudre la différence entre d'énormes tableaux. De plus, vous apprendrez à utiliser différentes techniques de gestion de la mémoire pour optimiser les performances lorsque vous travaillez avec de grandes baies.

1. Description du problème

Considérons un scénario : il y a deux tableaux, tous deux très grands, chaque tableau contient 100 000 éléments. Nous voulons maintenant trouver la différence entre ces deux tableaux. En termes simples, il s'agit de rechercher des éléments qui n'existent que dans un tableau. Voici l'implémentation du code :

<?php
$array1 = array();
$array2 = array();

// 初始化数组1,2,每个数组都有 10 万个元素
for($i=0;$i<1000000;$i++){
    $array1[$i] = $i;
    $array2[$i] = $i+1;
}

// 计算差集
$result = array_diff($array1, $array2);

print_r($result);
?>

Lorsque nous exécutons le code ci-dessus, nous constaterons que la page ne répond plus rapidement, puis une erreur est signalée indiquant que notre script PHP n'a plus de mémoire allouable. En effet, la limite de mémoire par défaut de PHP est de 128 Mo, ce qui n'est pas assez grand pour gérer de grands tableaux. Par conséquent, des algorithmes d’optimisation ou d’autres techniques de gestion de la mémoire doivent être envisagés pour résoudre ce problème.

2. Algorithme d'optimisation

Si les éléments du tableau sont déjà disposés dans l'ordre, vous pouvez utiliser un curseur pour accélérer la recherche, ce qui peut réduire le temps d'exécution et l'utilisation de la mémoire. Voici l'implémentation du code :

<?php
$array1 = array();
$array2 = array();

// 初始化数组1,2,每个数组都有 10 万个元素
for($i=0;$i<1000000;$i++){
    $array1[$i] = $i;
    $array2[$i] = $i+1;
}

// 排序数组1、2
sort($array1);
sort($array2);

// 初始化游标
$cursor1 = $cursor2 = 0;

// 计算差集
$result = array();
while($cursor1 < count($array1) && $cursor2 < count($array2)){
    if($array1[$cursor1] < $array2[$cursor2]){
        $result[] = $array1[$cursor1];
        $cursor1++;
    }
    elseif($array1[$cursor1] > $array2[$cursor2]){
        $cursor2++;
    }
    else{
        $cursor1++;
        $cursor2++;
    }
}

// 将数组1中剩余的元素添加入结果数组
while($cursor1 < count($array1)){
    $result[] = $array1[$cursor1];
    $cursor1++;
}

print_r($result);
?>

Le code ci-dessus optimisera le temps d'exécution et rendra l'utilisation de la mémoire plus efficace. Cependant, si le tableau n’est pas en ordre, cet algorithme ne fonctionnera pas.

3. Utiliser la technologie de traitement segmenté

En PHP, array_diff utilise une très grande surcharge de mémoire lors du traitement de grands tableaux. Cependant, le gestionnaire de mémoire de PHP maintient une table d'allocation de mémoire pour chaque allocation de mémoire. Ce tableau détecte la taille et l'emplacement de chaque allocation de mémoire. Par conséquent, vous pouvez utiliser la technologie de traitement de segmentation pour diviser un grand tableau en plusieurs petits sous-tableaux et traiter chaque sous-tableau séparément pour éviter d'occuper trop d'espace mémoire. Voici l'implémentation du code :

<?php
$array1 = array();
$array2 = array();

// 初始化数组1,2,每个数组都有 10 万个元素
for($i=0;$i<1000000;$i++){
    $array1[$i] = $i;
    $array2[$i] = $i+1;
}

// 分段,每段 10000 个元素
$chunkSize = 10000;
$chunks1 = array_chunk($array1, $chunkSize);
$chunks2 = array_chunk($array2, $chunkSize);

// 计算差集
$result = array();
foreach($chunks1 as $chunk1){
    $temp = array_diff($chunk1, array_merge(...$chunks2));
    $result = array_merge($result,$temp);
}

print_r($result);
?>

Dans le code ci-dessus, nous divisons le tableau en plusieurs sous-tableaux de taille 10 000 et les stockons dans les tableaux chunks1 et chunks2. Nous effectuons ensuite une boucle sur chunks1, utilisons array_diff pour calculer la différence entre chaque sous-tableau et chunks2, et ajoutons les résultats au tableau de résultats $result. Enfin, nous fusionnons $result dans le résultat final.

4. Utilisez des générateurs pour simuler des algorithmes de parcours

Une autre façon de résoudre le problème de mémoire des grands tableaux consiste à utiliser le générateur de PHP pour simuler le parcours consistant à trouver la différence entre deux tableaux. Les générateurs PHP vous permettent de générer les valeurs d'une séquence une par une, plutôt que de construire la séquence entière en mémoire. Voici l'implémentation du code :

<?php
$array1 = array();
$array2 = array();

// 初始化数组1,2,每个数组都有 10 万个元素
for($i=0;$i<1000000;$i++){
    $array1[$i] = $i;
    $array2[$i] = $i+1;
}

// 计算差集
$result = array();
function diff($arr1, $arr2) {
    sort($arr1);
    sort($arr2);
    $i = $j = 0;
    while($i < count($arr1) && $j < count($arr2)) {
        if($arr1[$i] < $arr2[$j]) {
            yield $arr1[$i];
            $i++;
        }
        elseif($arr1[$i] > $arr2[$j]){
            $j++;
        }
        else{
            $i++;
            $j++;
        }
    }
    while($i < count($arr1)) {
        yield $arr1[$i];
        $i++;
    }
}

// 遍历 generator
foreach (diff($array1, $array2) as $value) {
    $result[] = $value;
}

print_r($result);
?>

Dans le code ci-dessus, nous définissons une fonction diff qui utilise un générateur pour simuler le parcours de calcul de l'ensemble de différences de tableau. Cet algorithme utilise moins de mémoire et de temps CPU en triant les sous-tableaux séquentiellement, puis en utilisant la comparaison du curseur pour trouver la différence entre les deux tableaux.

5. Résumé

Dans le développement PHP, vous devez être particulièrement prudent lorsque vous utilisez des tableaux volumineux, car ils peuvent occuper trop de mémoire et provoquer un débordement de mémoire. Dans cet article, nous avons présenté des techniques telles que l'optimisation d'algorithmes, les techniques de traitement par morceaux et les algorithmes de parcours simulé par générateur qui peuvent être utilisés pour traiter de grands tableaux. La méthode que vous choisissez dépend de vos besoins et de votre environnement. En fonction de vos besoins, vous pouvez utiliser différentes techniques pour optimiser votre code afin d'améliorer les performances et la maintenabilité du code lorsque vous traitez de grands tableaux.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn