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 :

Plus de 600Mo de mémoire pour manipuler un fichier de 20Mo


Sujet :

Langage PHP

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Plus de 600Mo de mémoire pour manipuler un fichier de 20Mo
    Bonjour,

    je dois effectuer un traitement (une sorte de diff) sur des fichiers csv dont la taille peut aller jusqu'à 20Mo. La lecture du fichier via file() prend entre 9 at 15 secondes. Quand je découpe (via explode) les lignes, PHP utilise plus de 600Mo de mémoire (c'est la limite que j'ai positionné dans PHP.ini). Je ne comprend pas bien pourquoi aussi l'un d'entre vous pourrait-il m'éclairer sur la question ?

    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
     
    echo 'Begin process<br/>';
    flush();
    $a = time();
    $file = file("repository/SN1_20Mo.csv");
    echo "time to read 20Mo file: ".(time() - $a)."<br/>";
    flush();
     
    $a = time();
    $unrelevantLines = array();// il y a une dizaine de lignes (à peine quelque octets)
    foreach($file as $key=>$line) {
       if(preg_match("/^[0-9a-z-A-Z]/", $line) != 0) {
          $file[$key] = explode(";", $line); // c'est ici que ça plante à un moment donné
       } else {
          array_push($unrelevantLines, $key);
       }
    }
     
    foreach($unrelevantLines as $index) {
       unset($line[$index]);
    }
    echo "time to read csv lines of this 20Mo file: ".(time() - $a)."<br/>";
    flush();

    Merci

  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 : 39
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    A priori ton traitement doit être un peu lourd. 20Mo pour un csv, ça représente un paquet de lignes. Donc, un traitement avec un preg_match sur chaque ligne d'un (très) gros tableau...

    D'où questions : le traitement par preg_match est-il vraiment indispensable (qu'est-ce que contiennent ces fameuses unrevelant lines...) ? As-tu réellement besoin de garder toutes les lignes dans un tableau, qui plus est devient un tableau de tableaux ?
    et au passage, il existe une fonction fgetcsv conçue pour lire les lignes des fichiers csv, ça pourrait peut-être t'être utile

  3. #3
    Candidat au Club
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Les fichiers csv sont constitués d'une entête. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    # lignes
    # de 
    # mon
    # entête
     
    colName1;colname2;...;colNameN
    val1_1;val1_2;...;val1_N
    .....
    valP_1;valP_2;.....valP_N
    J'ai deux versions d'un même fichier, i.e le second fichier a des lignes en plus, en moins ou certaines lignes ont été modifiées.

    Mon algo doit identifier ces différentes lignes et pour les lignes modifiées indiquer le nom de la colonne, l'ancienne valeur et la nouvelle valeur (d'où le besoin du explode).

    Par contre, je n'ai aucune garantie sur l'ordre des lignes (une ligne est identifié par une colonne particulière (la PRIMARY KEY en gros)) d'où le besoin de charger l'ensemble des fichiers.

    les unrelevant lines correspondent à tout ce qui n'est pas nom de colonne ou valeur, i.e. fichier d'entête et l'espace entre le fichier d'entête et la ligne des noms de colonnes.

    Je ne peux pas utiliser fgetcsv à cause de l'entête.

    Je reste surpris que l'espace mémoire de 600Mo soit totalement utiliser juste pour le petit bout de code que j'ai posté.


    Je suis vraiment ouvert à toute suggestion.


    Merci.

  4. #4
    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 : 39
    Localisation : France

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 8 633
    Points : 16 372
    Points
    16 372
    Par défaut
    Moi je ferais comme ç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
    echo 'Begin process<br/>';
    flush();
    $a = time();
    $handle = fopen('repository/SN1_20Mo.csv', 'r');
    echo "time to read 20Mo file: ".(time() - $a)."<br/>";
    flush();
     
    $a = time();
    $unrelevantLines = array();// il y a une dizaine de lignes (à peine quelque octets)
    $file = array();
    while (!feof($handle)) 
    {
    	$line = fgets($handle);
    	if(preg_match("/^[0-9a-z-A-Z]/", $line) != 0)
    	{
    		$file[] = explode(";", $line);
    	}
    }
    fclose($handle);
     
    echo "time to read csv lines of this 20Mo file: ".(time() - $a)."<br/>";
    flush();
    Logiquement, à la fin dans $file tu as uniquement les lignes qui t'intéressent. Et c'est (peut-être) un peu moins lourd

Discussions similaires

  1. ruby itértion pour manipulation de fichiers
    Par phlam dans le forum Ruby
    Réponses: 2
    Dernier message: 20/11/2011, 22h38
  2. Programmation pour manipuler des fichiers XML
    Par anolo40 dans le forum Débuter
    Réponses: 8
    Dernier message: 09/08/2011, 22h29
  3. Librairie pour manipuler les fichiers DBF
    Par rahmoucha dans le forum Général Java
    Réponses: 3
    Dernier message: 26/11/2010, 09h03
  4. bibliothèque python pour manipulation de fichiers RAW (DNG ou NEF Nikon)
    Par methos1435 dans le forum Bibliothèques tierces
    Réponses: 0
    Dernier message: 10/09/2009, 21h00
  5. Réponses: 2
    Dernier message: 18/01/2003, 17h06

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