Avatar billede OlsnJensen Nybegynder
06. februar 2010 - 22:00 Der er 10 kommentarer og
1 løsning

Hjælp til at gøre script hurtigere.

Kan en af jer kloge hoveder hjælpe mig med at gøre dette script hurtigere? Har ikke testet slutningen endnu(med at putte i databasen), men hvor den skriver det ud som en tabel og det tog lang tid.

Det er denne der tager tid(tror jeg):
$raw = file_get_contents($url);

Jeg ved man kan løse safe_mode problemet med "@set_time_limit(0);" men den tager stadig LANG tid.

<?php

//skab forbindelse til database
XXXXXXXXX

//Fastsætter et link til URL
$url = "http://www.bold.dk/statistik/kampe.php?package=2";

// Henter kildekoden fra URL og fastsætter kildekoden til RAW
$raw = file_get_contents($url);

//Fastsætter en ARRAY
$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B");

//Fjerner alle linieskift
$content = str_replace($newlines, "", html_entity_decode($raw));

//Fastsætter startpunkt i kildekoden(CONTENT)
$start = strpos($content,'<table width="100%" border="0"');

//Fastsætter slutpunkt i kildekoden(CONTENT)
$end = strpos($content,'</table>',$start) + 8;

//Tager indholdet af kildekoden(CONTENT) imellem START og END
$table = substr($content,$start,$end-$start);

//Tager indholdet imellem <tr & <\tr> og gør dem til ARRAY(linie vis)
preg_match_all("|<tr(.*)</tr>|U",$table,$rows);

foreach ($rows[0] as $row){

    if ((strpos($row,'<th')===false)){
 
$domain = strstr($row, 'gameid');
$rest = substr("$domain", 0, 13);

  preg_match_all("|<TD(.*)</TD>|U",$row,$cells);
      $dato = strip_tags($cells[0][0]);
      $liga = strip_tags($cells[0][1]);
     

  preg_match_all("|<td(.*)</TD>|U",$row,$cells);
      $kamp = strip_tags($cells[0][0]);

$link = "http://www.bold.dk/statistik/headtohead.php?";
$url = $link . $rest;
if ($rest == "") {
//    echo "REST:$rest<-";
    }else{


$raw = file_get_contents($url);

$newlines = array("\t","\n","\r","\x20\x20","\0","\x0B");

$content = str_replace($newlines, "", html_entity_decode($raw));

$start = strpos($content,'Gennemsnit');

$end = strpos($content,'Sandsynlighed',$start) + 8;

$table = substr($content,$start,$end-$start);

preg_match_all("|<TR(.*)</TR>|U",$table,$rows);

foreach ($rows[0] as $row){

    if ((strpos($row,'<th')===false)){
 

    preg_match_all("|<td(.*)</TD>|U",$row,$cells);
        $et = strip_tags($cells[0][1]); 
        $kryds = strip_tags($cells[0][2]);
        $to = strip_tags($cells[0][3]);
   
    preg_match_all("|<TD(.*)</TD>|U",$row,$cells);
        $et1 = strip_tags($cells[0][1]);
        $kryds1 = strip_tags($cells[0][2]);
        $to1 = strip_tags($cells[0][3]);

//laver en forspørgsel i databasen
$svar = mysql_query("SELECT * FROM kampe WHERE kamp = \"$kamp\"");

while($test = mysql_fetch_array($svar))
    {
        if ($et == "")
        {
            echo "$kamp ikke gemt pga manglende odds <br>";
        }else{
        if ($kamp == $test[kamp])
        {
        //updatere databasen hvor kamp = kamp
        mysql_query("UPDATE kampe SET  1='$et',  kryds='$kryds',  to='$to', dato='$dato', kamp='$kamp', liga='$liga', gameid='$gameid' WHERE kamp ='$kamp'") or die(mysql_error());
        echo "Du har nu rettet kamp i din database.";       
        }else{
              //Indsæt info i databasen
              mysql_query("INSERT INTO kampe(1, x, 2, dato, kamp, liga, gameid)values('$et', '$kryds', '$to', '$dato', '$kamp', '$liga', '$gameid')");
              echo "$kamp er nu tilføjet i databasen.";
            }
        }
   
    }
     


    }
    }

}
 
    }

}




?>
Avatar billede repox Seniormester
06. februar 2010 - 22:16 #1
Jeg ved man kan løse safe_mode problemet med "@set_time_limit(0);" men den tager stadig LANG tid
Hvad i alverden betyder det? Du løser ikke noget safe_mode problem ved at sætte @ foran noget som helst og hvad skulle det set_time_limit(0); løse i forhold til tiden?

Nå, men ellers; ja, det vil tage dig lang tid at løbe alle de sider igennem som du vil. Det kan du ikke skære tiden ned på.
Du kan måske optimere dine SQL forespørgsler, men jeg tror næppe det vil give en mærkbar forskel.
Avatar billede OlsnJensen Nybegynder
06. februar 2010 - 22:31 #2
Vedrørende set_time_limit(0); så berører det scriptet i og med at de normale 60 sekunder udløber. Da mit webhotel køre i safe_mode kan jeg ikke sætte set_time_limit(0);. Jeg får ikke fejl når jeg skriver @ foran

Okay, håber der er nogen som kender en fidus. Eller nogle ideer til hvordan jeg kan dele den op - Jeg har nu testet scriptet og har ladet den køre i fem min og den blev ikke færdig:-(
Avatar billede repox Seniormester
06. februar 2010 - 22:40 #3
Jeg garanterer dig at undertrykke fejlen er lige så effektivt som at blot fjerne linien helt...

Uanset, så er der ikke nogen fidus. Alternativet er at - som du selv siger - dele det op. Læg de forskellige kampe en tilgængelig datakilde (mysql, txt fil eller noget) og kør dem manuelt en ad gangen istedet for at køre dem alle på en gang.

Normalt ville man også spørge efter et API eller en datakilde til at hente de data som du skal bruge, istedet for at trave websitet igennem for at finde de data du skal bruge. Typisk er det ikke noget problem; særligt ikke hvis man har fået lov til at tage deres data.
Avatar billede OlsnJensen Nybegynder
06. februar 2010 - 23:06 #4
API?

Er det muligt at travle alle kampene (kun hvem der møder hinanden), gemme det i databasen og derefter lave et script der søger i databasen og hvis fx database feltet "1" er tomt så travle kun den kamp?

Men hvordan henter jeg info ud kum om den kamp - et fif? Ellers må jeg bare prøve mig frem
Avatar billede repox Seniormester
06. februar 2010 - 23:29 #5
Et API kan være så mange ting; i dit tilfælde kunne du spørge udbyderen af de her data efter et XML feed, som du kunne tilgå, med de data (måske de endda allerede har et?) som du skal bruge.

Jeg kan ikke helt gennemskue hvad det er for nogle data du forsøger at hente, men nu har jeg heller ikke kigget din kode ordentligt igennem. Udover det forstår jeg mig heller ikke på sporten, så jeg får lidt svært ved at se sammenhængen i det i forhold til de data du kommer til at mangle.

Men du kunne jo tage den oprindelige side, som du finder kampene på, hente de links ned til de forskellige kampe og lægge dem i en datakilde som du kan tilgå med et andet interface og hente dem manuelt, en efter en.
Avatar billede acore Ekspert
07. februar 2010 - 11:15 #6
For at kunne optimere et script, skal du vide hvor tiden bruges.

Læg kald ind til microtime() og skriv resultatet ud.

Mit gæt er dog, at +90% af tiden går med kaldene til file_get_contents(...) og pre_match_all(...).

Det kan løses ved at læse siden og forbehandle data i et separat script, og så gemme resultatet lokalt. Dette script kan så køres en gang i timen, eller hvad der nu er passende, via et cronjob. Hvis dit web-hotel ikke understøtter cronjobs, kan du gøre det fra cronjob.de - det er gratis.

Nu vil du opleve, at dette script kører meget hurtigere, blot baserer det sig på "gamle" data (op til en time). Om det er en løsning for dig, ved jeg ikke.

Alternativt skal du få data på en anden måde (fx XML som en er inden på) eller optimere din preg_match_all kode. Men find først ud af, om det er der skoen trykker.
Avatar billede repox Seniormester
07. februar 2010 - 12:39 #7
#6
Jeg er ikke helt sikker på hvordan din besvarelse skiller sig ud fra min? Men udover det, så behøver det ikke at være et gæt at den eksterne trafik er en stor tidsrøver hvad angår performance, hvilket også er derfor jeg mener man bør kontakte udbyderen af disse data og gøre et API tilgængeligt, såfremt man naturligvis har den rette tilladelse til at indhente og anvende de oplysninger.

Mange gange er det også mere ønskeligt for udbyderen da alene ovenstående i skrivende stund vil generere knap 100 hits på siden - 100 hits som vil danne unikke sidevisninger da PHP stream wrapper ikke kan identificeres på andet end en IP. Der tages ikke højde for eventuelle cookies eller andet i forbindelse med statistik.

Lad os antage at OP så vil anvende scriptet bare 10 gange om måneden; så er vi oppe på 1000 hits som ødelægger den generelle statistik. Jeg ville nok hurtigt få blokeret den IP som var skyld i det.

Jeg synes sjældent man oplever man ikke kan komme frem til en aftale der kan gavne begge sider. I det her tilfælde ville et sidekald til et XML API være mere ønskeligt for bold.dk, da disse kald kan udelades af den normale statistik - og hvis bold.dk kan få et promotional link på OP's side som 'tak for hjælpen', så har OP endda et SEO link som kan gavne både han og bold.dk.
Avatar billede acore Ekspert
07. februar 2010 - 16:54 #8
@repox:
Min besvarelse adskiller sig ved at jeg konkret foreslår at se på hvor problemet ligger - mit gæt er file_get_contents og/eller preg_match_all. Det er væsentligt, for det første kan løses fx med dit forslag, mens det andet må løses på anden vis.

Min besvarelse skulle ikke læses i modsætning til dine svar (hvilket jeg ikke håber fremgår af den), men med den indfaldsvinkel, at man kunne bruge microtime til at fastslå hvor problemet ligger, så man ikke behøver gætte.
Avatar billede OlsnJensen Nybegynder
09. februar 2010 - 20:30 #9
Jeg siger tak for hjælpen men fik en ven til at klare det - Han delte scriptet op.
Avatar billede repox Seniormester
09. februar 2010 - 21:14 #10
Jamen, din taknemmelighed er hermed noteret.
Avatar billede acore Ekspert
20. februar 2010 - 19:47 #11
Enig ;)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester