IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Optimisation code PHP


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de la_chouette
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 183
    Par défaut Optimisation code PHP
    Bonjour,

    Le code PHP ci-dessous permet de parser puis d’afficher et paginé le contenu d’un fichier texte contenant plus de 830 000 lignes.

    Le problème est qu’il utilise plus de mémoire qu’il n'ait allouée à PHP, c’est-à-dire 128mo.

    Avez-vous des recommandations sur l’optimisation du code PHP pour baisser la consommation de mémoire lors de son exécution ?

    Merci de votre aide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <?php
    $lines = file_get_contents('file.txt');
     
    $perpage = 5; //Number of lines per page
     
    $searchString = $_GET['search']; //Insert word(s) you're searching for
    $pattern = preg_quote($searchString, '/');
    $pattern = "/^.*$pattern.*/mi";
     
    if(preg_match_all($pattern, $lines, $matches)){
        $line_amount = count($matches[0]);
    } else {
        echo "No matches found";
    }
     
    $p = isset($_GET['page']) ? $_GET['page'] : 1;
    for ($i = (($p * $perpage) - $perpage); $i <= (($perpage * $p) - 1); $i++){
        if($i >= $line_amount){
            break;
        } else {
            echo $matches[0][$i].'<br />';
        }
    }
    ?>
     
    <table summary="" cellpadding="10" cellspacing="0"  border="0">
        <tr>
    	<?php
    	$link = "";
    	$page = $_GET['page']; // your current page
    	$pages=$line_amount/$perpage; // Total number of pages
     
    	$perpage=5  ; // May be what you are looking for
     
        if ($pages >=1 && $page <= $pages)
        {
            $counter = 1;
            $link = "";
            if ($page > ($perpage/2))
    			$link .= "<td><a href=\"?page=1\">1 </a></td> <td>...</td> ";
     
            for ($x=$page; $x<=$pages;$x++)
            {
                if($counter < $perpage)
                    $link .= "<td><a href=\"?page=" .$x."\">".$x." </a></td>";
     
                $counter++;
            }
            if ($page < $pages - ($perpage/2))
    				$link .= "<td>...</td> " . "<td><a href=\"?page=" .$pages."\">".$pages." </a></td>";
        }
     
        echo $link;
    	?>
    	</tr>
    </table>

  2. #2
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    Avril 2007
    Messages
    8 633
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Par défaut
    Le principal problème de ton script est qu'il lit la totalité du fichier, qu'il passe la regex sur la totalité des lignes et ensuite seulement il filtre les résultats de la pagination.

    Un axe d'optimisation serait de découper la lecture du fichier en plusieurs parties, par exemple par bloc de 1000 lignes, histoire de ne pas avoir la totalité du fichier en mémoire. Tu lis, tu parses, tu conserves uniquement les lignes qui t'intéressent et tu recommences jusqu'à la fin du fichier.
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  3. #3
    Membre très actif Avatar de la_chouette
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 183
    Par défaut
    Bonjour celira,

    effectivement, j'applique ton conseil tout de suite.

    Merci

  4. #4
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 506
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 506
    Par défaut
    Pas sur que cela dégrossise mais essaye déjà ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    <?php
     
    $lines = file_get_contents('file.txt');
     
    $perpage = 5; //Number of lines per page
     
    $searchString = $_GET['search']; //Insert word(s) you're searching for
    $pattern = preg_quote($searchString, '/');
    $pattern = "/^.*$pattern.*/mi";
     
    if (preg_match_all($pattern, $lines, $matches)) {
        $line_amount = count($matches[0]);
    } else {
        echo "No matches found";
    }
     
    //$p = isset($_GET['page']) ? $_GET['page'] : 1;
     
    $p = 1;
    if($_GET['page'])
    {
        $p = $_GET['page'];
    }
     
    $i_perpage = ($p*$perpage- - $perpage;
    $i_lte_perpage = ($perpage * $p) - 1;
     
    for ($i = $i_perpage; $i <= $i_lte_perpage; $i++) {
        if ($i >= $line_amount) {
            break;
        } else {
            echo $matches[0][$i] . '<br />';
        }
    }
    ?>
     
    <table summary="" cellpadding="10" cellspacing="0" border="0">
        <tr>
            <?php
            $link = "";
            $page = $_GET['page']; // your current page
            $pages = $line_amount / $perpage; // Total number of pages
     
            $perpage = 5; // May be what you are looking for
     
            if ($pages >= 1 && $page <= $pages) {
                $counter = 1;
                $link = "";
                if ($page > ($perpage / 2))
                    $link .= "<td><a href=\"?page=1\">1 </a></td> <td>...</td> ";
     
                for ($x = $page; $x <= $pages; $x++) {
                    if ($counter < $perpage)
                        $link .= "<td><a href=\"?page=" . $x . "\">" . $x . " </a></td>";
     
                    $counter++;
                }
                if ($page < $pages - ($perpage / 2))
                    $link .= "<td>...</td> " . "<td><a href=\"?page=" . $pages . "\">" . $pages . " </a></td>";
            }
     
            echo $link;
            ?>
        </tr>
    </table>

  5. #5
    Membre très actif Avatar de la_chouette
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 183
    Par défaut
    Bonjour MaitrePylos,

    Merci de ton aide.

    Le code PHP utilise toujours trop de mémoire, je pense que je dois d’abord limiter le nombre de données lue/chargée en mémoire comme préconiser par celira et ensuite optimisé le traitement.

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 994
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 994
    Par défaut
    Oui, je suis d'accord avec Celira. D'ailleurs tu n'as pas besoin d'une regex (qui ne recherche qu'une sous-chaîne litérale). Si tu travailles ligne par ligne avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $fh = fopen("file.txt", "r");
    if ($fh) {
        while (($line = fgets($fh)) !== false) {
            ...
    Il te suffit d'utiliser la fonction stripos pour savoir si la ligne contient le motif de recherche (donc plus besoin de preg_quote non plus), ça n'en sera que plus rapide.

  7. #7
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 693
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 693
    Par défaut
    En version SPL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $file = new SplFileObject("fichier.txt");
    $results = array();
    while (!$file->eof()) {
        $line = $file->fgets();
        if(strripos($line,$recherche) !== false) {
            $results[] = $line;
        }
    }
    https://secure.php.net/manual/fr/cla...fileobject.php

    L'avantage c'est que tu peux sauter directement à une ligne donnée si tu sais ou aller et donc ne pas tout lire.
    Tu pourrais donc imaginer la construction d'un index pour accélérer les accès à ton fichier si il sont récurrents.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $file = new SplFileObject("fichier.txt");
    $file->seek(1234); //Saut à la ligne 1234
    echo $file->current(); // Affiche la ligne
    Dans tous les cas il faut si possible éviter les regex sur des traitements aussi lourd.
    Pry Framework php5 | N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre très actif Avatar de la_chouette
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    183
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 183
    Par défaut
    Merci pour conseils CosmoKnacki et grunk.

    En faites je ne saisi pas comment traiter le fichier ligne par ligne (comme vous me conseiller) en affichant 100 résultats par page tout en gérant la pagination.

    Je suis forcement obliger de stocker en mémoire le volume de données renvoyer (sur un fichier de 830 000 lignes minimum, je peux avoir 300 000 lignes de résultat pour une recherche que je dois afficher via une pagination).

    En googlisant, je viens de tomber sur une petite astuce concernant la mémoire utiliser par php : http://www.bigeng.io/php-memory-optimization/

Discussions similaires

  1. [MySQL] Optimisation de Code Php Jquery
    Par PainkillerDev dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 09/07/2013, 18h18
  2. Optimisation de code php
    Par Oprichnik dans le forum Humour Informatique
    Réponses: 2
    Dernier message: 16/04/2011, 21h53
  3. Optimisation du code PHP vs SQL
    Par persia dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 18/11/2010, 21h10
  4. Optimisation de code PHP
    Par MeHo_ dans le forum Langage
    Réponses: 9
    Dernier message: 29/04/2009, 12h21
  5. Question optimisation de code PHP/HTML
    Par heavenvibes dans le forum Langage
    Réponses: 7
    Dernier message: 14/08/2008, 12h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo