Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [PHP] Velocizzare lettura file

    Salve ho scritto un programmino in php che dovrebbe leggermi dei file con una struttura
    specifica del tipo:

    codice:
    [ITEMDEF ffffff]
    DEFNAME=defname
    NAME=name
    ID=id
    TYPE=type
    CATEGORY=category
    SUBSECTION=subsection
    DESCRIPTION=description
    Tutti i campi sono opzionali tranne itemdef che fa da chiave primaria.
    Devo leggere circa 12000 itemdef ed il mio script ci mette circa 14 secondi, probabilmente
    per il forte uso di espressioni regolari.
    L'unico modo che ho di sapere che č finita la struttura č l'incontro di un altro itemdef.
    Sapreste indicarmi un modo per migliorare le prestazioni di inserimento su db con mysql?
    Utilizzo apache+mysql+php aggiornati all'ultima versione.
    Ecco il codice:

    Codice PHP:
    <?php

    // Includo il file di configurazione con i parametri.
    include("config.inc.php");

    // Funzione di conversione del tempo.
    function microtime_float()
    {
        list(
    $usec$sec) = explode(" "microtime());
        return ((float)
    $usec + (float)$sec);
    }

    // Memorizzo l'istante di inizio dello script.
    $time_start microtime_float();

    // Connessione al database.
    $db mysql_connect($db_host$db_user$db_password);
    if (
    $db == FALSE)
        die (
    "Errore nella connessione. Verificare i parametri nel file config.inc.php");

    // Selezione del database.
    mysql_select_db($db_name$db) or die ("Errore nella selezione del database. Verificare i parametri nel file config.inc.php");

    // Directory dei files da analizzare.
    $dir "./scripts/";

    $itemdef=NULL;
    $defname=NULL;
    $name=NULL;
    $id=NULL;
    $type=NULL;
    $category=NULL;
    $subsection=NULL;
    $description=NULL;

    // Apro la directory contenente gli scripts.
    if ($handle opendir($dir))
    {
        
    // Scorro i vari files contenuti dalla directory.
        
    while (FALSE !== ($file_name readdir($handle)))
        {
            
    // Escludo dalla ricerca "." e "..".
            
    if ($file_name != "." && $file_name != "..")
            {
                
    // Apro il file trovato nella directory.
                
    $file fopen($dir.$file_name"r") or die("Errore nell'apertura del file $file_name.\n");
                
    // Scorro il suddetto file riga per riga fino a eof.
                
    while(!feof($file))
                {
                    
    // Scorro le righe del file.
                    
    $file_row=ltrim(fgets($file));
                    
                    
    // Itemdef.
                    
    if(eregi('^\[itemdef ',$file_row))
                    {
                        if(
    $itemdef != NULL)
                        {
                            
    // Inserisco le informazioni lette riguardanti l'item precedente nel database.
                            
    $query "INSERT INTO item VALUES ('$itemdef','$defname','$name','$id','$type','$category','$subsection','$description')";
                            
    $result=mysql_query($query$db) or die ("Errore durante l'esecuzione della query.\n");

                            
    // Svuoto le variabili per la prossima query.
                            
    $defname=NULL;
                            
    $name=NULL;
                            
    $id=NULL;
                            
    $type=NULL;
                            
    $category=NULL;
                            
    $subsection=NULL;
                            
    $description=NULL;
                        }

                        
    // Individuo dove finisce l'id dell'item in questione.
                        
    $itemdef_len=strpos($file_row,']');
                        
    // Estraggo il valore pulito dell'id dell'item.
                        
    $itemdef=trim(strtolower(substr($file_row,9,($itemdef_len 9))));
                    }
                    
    // Defname.
                    
    else if(eregi('^defname=',$file_row))
                    {
                        
    // Estraggo il valore pulito del defname dell'item.
                        
    $defname=trim(addslashes(strtolower(substr($file_row,8))));
                    }
                    
    // Name.
                    
    else if(eregi('^name=',$file_row))
                    {
                        
    // Estraggo il valore pulito del name dell'item.
                        
    $name=trim(addslashes(strtolower(substr($file_row,5))));
                    }
                    
    // Id.
                    
    else if(eregi('^id=',$file_row))
                    {
                        
    // Estraggo il valore pulito dell'id dell'item.
                        
    $id=trim(addslashes(strtolower(substr($file_row,3))));
                    }
                    
    // Type.
                    
    else if(eregi('^type=',$file_row))
                    {
                        
    // Estraggo il valore pulito del type dell'item.
                        
    $type=trim(addslashes(strtolower(substr($file_row,5))));
                    }
                    
    // Category.
                    
    else if(eregi('^category=',$file_row))
                    {
                        
    // Estraggo il valore pulito della category dell'item.
                        
    $category=trim(addslashes(strtolower(substr($file_row,9))));
                    }
                    
    // Subsection.
                    
    else if(eregi('^subsection=',$file_row))
                    {
                        
    // Estraggo il valore pulito della subsection dell'item.
                        
    $subsection=trim(addslashes(strtolower(substr($file_row,11))));
                    }
                    
    // Description.
                    
    else if(eregi('^description=',$file_row))
                    {
                        
    // Estraggo il valore pulito della description dell'item.
                        
    $description=trim(addslashes(strtolower(substr($file_row,12))));
                    }
                }

                if(
    $itemdef!= NULL)
                {
                    
    // Chiudo la query del primo o dell'ultimo itemdef lasciata in sospeso.
                    
    $query "INSERT INTO item VALUES ('$itemdef','$defname','$name','$id','$type','$category','$subsection','$description')";
                    
    $result=mysql_query($query$db) or die ("Errore durante l'esecuzione della query.\n");
                }

                
    //Azzero gli attributi dell'item.
                
    $itemdef=NULL;
                
    $defname=NULL;
                
    $name=NULL;
                
    $id=NULL;
                
    $type=NULL;
                
    $category=NULL;
                
    $subsection=NULL;
                
    $description=NULL;

                
    // Chiudo il file corrente.
                
    fclose($file);
            }
        }

        
    // Memorizzo l'istante di fine dello script.
        
    $time_end microtime_float();

        
    // Calcolo il tempo trascorso per l'esecuzione dello script.
        
    $time_elapsed $time_end $time_start;

        
    // Formatto $time_elapsed.
        
    $time_elapsed number_format($time_elapsed,5,',','.');

        
    // La query č andata a buon fine.
        
    echo "La query ha impiegato $time_elapsed secondi.
    "
    ;
        
        
    // Chiudo la connessione al database.
        
    mysql_close($db);
        
        
    // Chiudo la directory.
        
    closedir($handle);
    }

    ?>

  2. #2
    Perchč usare eregi() quando un substr() č piā che sufficiente?

  3. #3
    Originariamente inviato da filippo.toso
    Perchč usare eregi() quando un substr() č piā che sufficiente?
    Beh devo essere sicuro che la riga file inizi con una certa stringa e non che la
    contenga semplicemente, ma magari c'č un modo di utilizzare substr() che mi sfugge. :master:

  4. #4
    Puoi provare qualcosa del genere:

    Codice PHP:
    <?php
    $fp 
    fopen('data.txt''r');
    $data = array();
    while (!
    feof($fp)) {
        
    $line rtrim(fgets($fp));
        if (
    strpos($line'ITEMDEF')) {
               if (!empty(
    $data)) {
                
    // esegui query inserimento usando l'array $data
                
    $data = array();
            }
        } else {
            list(
    $key$val) = explode('='$line);
            
    $data[strtolower($key)] = $val;
        }
    }
    // esegui query inserimento usando l'array $data
    ?>
    una domanda: ogni itemdef contiene tutti i campi sempre?

  5. #5
    Parlando del db, hai provato a commentare gli inserimenti e vedere il tempo di esecuzione di quanto migliora? Perchč probabilmente sono gli insert a mangiarsi la maggior parte del tempo.

    Una prova che puoi fare č usare insert multiriga tipo:
    codice:
    INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
    Magari cominci con 100 inserimenti alla volta. E vedi se migliora la situazione.
    dA .. foto di viaggio
    L'esperienza č il tipo di insegnante pių difficile.
    Prima ti fa l'esame, e poi ti spiega la lezione.

  6. #6
    Originariamente inviato da ^EvAmPiReS^
    Beh devo essere sicuro che la riga file inizi con una certa stringa e non che la
    contenga semplicemente, ma magari c'č un modo di utilizzare substr() che mi sfugge.
    Se devi essere sicuro che la riga file inizi con una certa stringa č sufficiente verificare che i primi X caratteri della riga siano uguali ad una certa stringa, ovvero, devi estrarre i primi X caratteri della riga e confrontarli con una certa stringa, dove X č la lunghezza di una certa stringa. Piuttosto elementare direi.

  7. #7
    Originariamente inviato da filippo.toso
    Se devi essere sicuro che la riga file inizi con una certa stringa č sufficiente verificare che i primi X caratteri della riga siano uguali ad una certa stringa, ovvero, devi estrarre i primi X caratteri della riga e confrontarli con una certa stringa, dove X č la lunghezza di una certa stringa. Piuttosto elementare direi.
    @filippo.toso:
    Non te la prendere filippo.toso il mio grassetto era assolutamente innocuo
    Comunque seguiro' il tuo consiglio ed userō substr() per evitare eregi().
    Grazie.

    @AnĒkin:
    Ho salvato tutti i dati dentro una matrice ed eseguo la INSERT multipla solo alla fine di ogni file.
    Ci impiega 2 secondi ora

    @k.b.
    No l'unico campo obbligatorio (chiave) č itemdef gli altri sono tutti opzionali.
    Tu che ne dici, c'č una struttura dati migliore di una matrice a 7 (come gli attributi) colonne?
    Pensavo di usare l'itemdef come chiave di una tabella o lista ma non conosco il php :master:

  8. #8
    Non serve una matrice, basta un singolo array come nel codice di prova che ti ho postato. Crei l'array scorrendo riga per riga, quando incontri un itemdef esegui la query e svuoti l'array per poi ripopolarlo dalla riga successiva.

    La query la costruisci prendendo dall'array solo i valori presenti: se i nomi delle colonne della tabella nel database sono uguali ai campi che appaiono prima dell'uguale, allora si fa immediatamente; se sono diversi basta usare un altro array "di traduzione".

  9. #9
    Originariamente inviato da k.b
    Non serve una matrice, basta un singolo array come nel codice di prova che ti ho postato. Crei l'array scorrendo riga per riga, quando incontri un itemdef esegui la query e svuoti l'array per poi ripopolarlo dalla riga successiva.

    La query la costruisci prendendo dall'array solo i valori presenti: se i nomi delle colonne della tabella nel database sono uguali ai campi che appaiono prima dell'uguale, allora si fa immediatamente; se sono diversi basta usare un altro array "di traduzione".
    Ma in questo modo ogni volta che trovo un itemdef dovrei farmi una INSERT ed invece
    io preferirei fare un'unica query per file (come ho giā scritto per questioni di velocitā)...

  10. #10
    Hai ragione, la mia ignoranza in campo (my)sql e' ancora profonda e nemmeno conoscevo gli insert multipli... ora si

    In alternativa alla matrice, puoi costruire la stringa della query un po' per volta, ma non so se c'e' differenza in velocita' di esecuzione.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.