[PHP] 3198 explode's 4.9 sec.. Snellere optie?

Pagina: 1
Acties:

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Een (eeh, veel) logbestand(en) van 3198 regels, comma-seperated.. Ik heb de losse velden nodig. Dus: explode! :) Maar nee, dat duurt dus 4.9 seconde :'( Weet een van jullie een snellere oplossing?

preg_split of split zijn niet sneller (duh).. Maar het zou zo handig zijn als het wél sneller kon (weer duh)..

  • tomato
  • Registratie: November 1999
  • Niet online
Wat wil je ermee doen? Moet het allemaal in een array, of is dat niet nodig?

Verwijderd

lees niet de hele file in een keer?

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Doe ik al niet... fopen en while (!feof($fd))

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op zaterdag 20 april 2002 17:47 schreef tomato het volgende:
Wat wil je ermee doen? Moet het allemaal in een array, of is dat niet nodig?
Ja.. Het zijn 8 'velden', en alleen de 4e heb ik niet nodig

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Programmer - an organism that turns coffee into software.


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op 3198 regels:
fgets + explode: 4.77108 sec
fgetcvs: 4.79465 sec

Thanx voor de tip trouwens.. Ik kende hem nog niet.. Helaas is het langzamer (wazig genoeg)!

Andere ideeën? Maakt het iets uit dat ik van het eerste veld weet dat het een datetime-veld is (en dus een vaste lengte heeft)? Een fgets, substr en explode is niet sneller, maar misschien brengt het jullie op ideeën?

  • tomato
  • Registratie: November 1999
  • Niet online
Maar wat doe je nu precies? Tijdens het inlezen split je ook direct alle velden uit iedere regel? Wat ga je doen met die velden, is dit echt nodig?

Is het wellicht sneller om in een keer in te lezen (alle regels in een array) en er vervolgens andere dingen mee te doen?

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op zaterdag 20 april 2002 18:04 schreef tomato het volgende:
Maar wat doe je nu precies? Tijdens het inlezen split je ook direct alle velden uit iedere regel? Wat ga je doen met die velden, is dit echt nodig?

Is het wellicht sneller om in een keer in te lezen (alle regels in een array) en er vervolgens andere dingen mee te doen?
Ik heb ze gesplit nodig, zodat ik kan groeperen erna.. In het logbestand staan oa hits, die ik per uur bij elkaar wil optellen. Dus het eerste veld is een datum-veld. Dan pak ik daarvan het uur, en maak er een array-element-key van. In dat array-element tel ik dan alle hits bij elkaar op.

Nou is niet alleen de datum van belang, maar ook de 6 andere velden (7e is hits, 8e heb ik niet nodig).

Helemaal inlezen in een array en op die elements (de lijnen uit het bestand dus) gaan exploden werd mij hier afgeraden.. En dat kan ik me ook wel voorstellen; De logs zijn nu nog 'klein'.. Het zoudeb zomaar ineens heel veel MEER regels kunnen gaan worden.. 20000 per logbestand ofzo :?

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 27-08 13:53

chem

Reist de wereld rond

hebben de regels een fixed-length structuur (dus char 15-31 bv. voor kolom 3)?
hoeveeltijd ben je kwijt aan het inladen van de file?
Laat eens een regeltje zien? Wat wil je er nou mee doen?

Klaar voor een nieuwe uitdaging.


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op zaterdag 20 april 2002 18:08 schreef chem het volgende:
hebben de regels een fixed-length structuur (dus char 15-31 bv. voor kolom 3)?
hoeveeltijd ben je kwijt aan het inladen van de file?
Laat eens een regeltje zien? Wat wil je er nou mee doen?
Nee, want er zit ook een IP in én het aantal hits kan ook tussen de 1 en de 1000 zitten.

Verwijderd

PHP:
1
<?$uitvoerarray = array();$temparray = array();$buffer = "";$fp = fopen("file","r");while(!feof($fp)){  $char = fgets($fp,2); //staat op php.net dat het 2 moet zijn  if($char == "\n"){    $uitvoerarray[] = $temparray;    $temparray = array();  } else if($char == ",")    $temparray[] = $buffer;    $buffer = "";  } else {    $buffer .= $char;  }}?>

Net even uit men duim gezogen

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Dit is de handmatige versie van explode.. En helaas: niet sneller :'(

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Helaas... Ik kom tot de :'( treurige conclusie (denk ik??) dat er niets sneller is dan een explode.. Anders hadden de luitjes @php het wel gemaakt right?
Damn jammer! :'(

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Laat de code eens zien die jij hebt gebruikt??

Programmer - an organism that turns coffee into software.


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
die is te plain forward maar oke:
PHP:
1
<?while (!feof ($openfile)) {  $line = fgets ($openfile, 4096);  $line = explode (",", $line);} // while?>

Om deze code heb ik een tijd-printertje gezet, en bij bestanden met 3198 regels doet ie HIEROVER dus 4.9 sec :( Veel te optimaliseren valt er niet hè?

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

PHP:
1
<?  $string=file("/www/log/access_log");  $microtime=microtime();   echo "<BR>";  foreach($string as $v)  {    list(,,,,,,$file,,)=explode(" ",$v);    $i++;  }  echo $microtime,":" ,microtime(),":",$i;?>

2,2 seconden
27745 Regels...

Programmer - an organism that turns coffee into software.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Ik kan me voorstellen dat het sneller kan door je invoerbestand door een UNIX utility als cut (-f, -d) te pipen en met PHP alleen de voorbewerkte regels in te lezen (die dan dus uitsluitend de kolom die je nodig hebt bevatten). Ook kun je eventuele oninteressante regels er dan uitfilteren met grep.

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
En hoeveel explodes zaten daarin? Ook ongeveer 3198? Dit draait op een celeron 466 trouwens..

  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Op zaterdag 20 april 2002 18:34 schreef Soultaker het volgende:
Ik kan me voorstellen dat het sneller kan door je invoerbestand door een UNIX utility als cut (-f, -d) te pipen en met PHP alleen de voorbewerkte regels in te lezen (die dan dus uitsluitend de kolom die je nodig hebt bevatten). Ook kun je eventuele oninteressante regels er dan uitfilteren met grep.
Maar niet iedereen heeft UNIX en niet iedereen heeft de mogelijk heid om exec / system commando's te gebruiken....

Programmer - an organism that turns coffee into software.


  • LuCarD
  • Registratie: Januari 2000
  • Niet online

LuCarD

Certified BUFH

Op zaterdag 20 april 2002 18:34 schreef elviver het volgende:
En hoeveel explodes zaten daarin? Ook ongeveer 3198? Dit draait op een celeron 466 trouwens..
ermm... 27745 explodes op een P2 266 met G@H running :)

Programmer - an organism that turns coffee into software.


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op zaterdag 20 april 2002 18:34 schreef Soultaker het volgende:
Ik kan me voorstellen dat het sneller kan door je invoerbestand door een UNIX utility als cut (-f, -d) te pipen en met PHP alleen de voorbewerkte regels in te lezen (die dan dus uitsluitend de kolom die je nodig hebt bevatten). Ook kun je eventuele oninteressante regels er dan uitfilteren met grep.
Hee, cut is misschien handig! :D Eens testen! Werkt zoiets ook op een windows-machine?
Helaas zijn er geen onnuttige regels in een log-bestand..

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Op zaterdag 20 april 2002 18:36 schreef LuCarD het volgende:

[..]

ermm... 27745 explodes op een P2 266 met G@H running :)
Ik snap dit echt niet! Die simpele code van mij net duurt echt 5 seconde voor die 3198 regels! Maar met een list inderdaad gaat het ineens wel HEEL veel sneller!??!? Zelfs als ik het bestand per regel inlees!
Trying trying trying!! :D (/me hoopt again)

  • tomato
  • Registratie: November 1999
  • Niet online
Veel tools uit de unix wereld zijn ook voor Windows te krijgen.

(Waarvan Perl natuurlijk de mooiste is >:))

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 09-09 11:02
Op zaterdag 20 april 2002 18:38 schreef elviver het volgende:
Werkt zoiets ook op een windows-machine?
Zit vast wel in de set basisutillities van Cygnus voor Windows (www.cygwin.com).

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Het verscheen heel rap op mijn console, maar in PHP was het verschil miniem te noemen.

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 27-08 13:53

chem

Reist de wereld rond

probeer eens je code te testen met je volledige content in een var, en die includen.

Je kan dan kijken naar je 'echte' code, zonder je fget() crap eromheen.

Volgens mij is it nl. nog een van de snelste methodes:
PHP:
1
<?$src = fread(($fp = fopen('file','r'),filesize('file'));fclose($fp);foreach(explode($src,"\n") as $line){    list(,,,,$file[],,,) = explode($line,',');}?>

Klaar voor een nieuwe uitdaging.


  • Erik Jan
  • Registratie: Juni 1999
  • Niet online

Erik Jan

Langzaam en zeker

elviver:

[Fixed length idee]

Nee, want er zit ook een IP in én het aantal hits kan ook tussen de 1 en de 1000 zitten.
Misschien is het toch wel het proberen waard, gewoon max lengte reserveren voor IP en aanvullen met spaties...Met 12 chars voor aantal hits moet je ook wel ff vooruit kunnen denk ik ;) (jaja "640kB should be enough for anyone" :))

This can no longer be ignored.


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 08-09 17:10
Ik maak die logs niet.. Dat doet een programma.. Daar kan ik weinig aan verbouwen helaas
Pagina: 1