[php / browser] problemen lange execution time

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ik heb een scrippie geschreven dat combinaties van karakters wegschrijft in een file. En dat duurt nogal lang. Om te zorgen dat ie niet na 30 seconde al een timeout gaf heb ik set_time_limit(0); gezet, maar het probleem is nu dat ie na een minuutje of 6 a 7 alsnog kapt. Ik krijg dan een Page Cannot Be Displayed - alsof de pagina niet bestaat.
Ik weet eigenlijk niet eens zeker of dit nu aan m'n browser ligt of aan php. iemand een idee? en een idee hoe ik dit op kan lossen?

Acties:
  • 0 Henk 'm!

Verwijderd

Waar het precies mee te maken heeft, weet ik niet, ik heb het probleem ook weleens gehad. Mijn oplossing was om het script (in mijn geval een paar tijdrovende lussen) in een paar delen uit te voeren.
Je zou dmv Javascript of een header("location: http://..."); naar het volgende deel van je script kunnen gaan.

Succes ermee :)

Acties:
  • 0 Henk 'm!

  • rickmans
  • Registratie: Juli 2001
  • Niet online

rickmans

twittert

je kan steeds een stukje info naar de browser sturen zodat de pagina steeds wat nieuwe info krijgt. Daarnaast kan je misschien ook je script posten, want misschien zit daar een fout in.

Don't mind Rick


Acties:
  • 0 Henk 'm!

  • ta_chi79
  • Registratie: Juli 2001
  • Laatst online: 17-09 22:43
Probeer je script eens direct uit te voeren dmv "php c:\scrippie.php" via de commandline.
Kun je gelijk zien of dat php ermee ophoud of dat je browser het wachten zat is.
Indien je browser ongeduldig wordt moet je even checken of je in ieder geval al iets naar je browser stuurt aan het begin van je script zoals html headers of zo.

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Mijn methode is bij zoiets altijd periodiek wat af te drukken en dat te flushen, iig helemaal aan het begin. ob_implicit_flush() setten is ook wel handig daarbij.

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ta_chi79 schreef op 20 juni 2003 @ 21:56:
Probeer je script eens direct uit te voeren dmv "php c:\scrippie.php" via de commandline.
Kun je gelijk zien of dat php ermee ophoud of dat je browser het wachten zat is.
Indien je browser ongeduldig wordt moet je even checken of je in ieder geval al iets naar je browser stuurt aan het begin van je script zoals html headers of zo.
Da's een goeie! Ik had me niet bedacht dat ik het wellicht ook onder de prompt zou kunnen uitvoeren. Gelukkig beschik ik over een linuxbak waar ik onder de prompt kan komen dus ben daar nu mee bezig. Het lijkt vooralsnog goed te gaan. Maar het is nogal een oud beesie dus gaat wel ff duren voordat ik zeker weet dat ie het tot het einde uitvoert

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
jup, hij's nou zeker al een goed half uur bezig zonder morren. het werkt dus!
thnx

dit is trouwens het script wat ik gemaakt heb:

PHP:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
error_reporting(E_ALL);
set_time_limit(0);

 /****
  * $pos is an array which contains numerical values that correspond to the keys of the values in $characters
  * each key in $pos serves as a slot that contains these values.
  * so, the value in each slot represents a key in $characters
  */
    
 // this funtion increases the values in each of the 'slots' in $pos
function increase(&$pos, $length, $characters)
{
    if ($length > 0)
    {
         // $length will trigger the right 'slot'.
        if ($pos[$length] < (count($characters)-1))
            $pos[$length]++;
         // if the value in that 'slot' is greater then the key-value in characters,
         // we need to move on to the next slot
        else
        {
            increase(&$pos, ($length-1), $characters);
            $pos[$length] = 0;
        }
        return True;
    }
     // if $length is 0 we've reached the last posibility (actually we've passed it)
    else
        die("mooi weest");
}
 // function that checks if a combination of 3 of the same succesive characters occur in the string
 // if so, we return False, indicating this string should not be saved
function check_string($pos, $characters)
{
    $threshold = 1;
    foreach ($pos AS $value)
    {
         // we increase the threshold if the last inserted string (in a 'slot') is the same as the current one
         // this is case INsensitive
        if (isset($old_value) && strtolower($old_value) == strtolower($value))
            $threshold++;
        else
            $threshold=1;
        if ($threshold == 3)
        {
            return False;
            break;
        }
        $old_value = $value;
    }
    return True;
}

$characters = array(
        "0","1","2","3","4","5","6","7","8","9",
        "a","b","c","d","e","f","g","h","i","j","k","l","m",
        "n","o","p","q","r","s","t","u","v","w","x","y","z",
        "A","B","C","D","E","F","G","H","I","J","K","L","M",
        "N","O","P","Q","R","S","T","U","V","W","X","Y","Z");
/* $characters = array(
        "0","1","2","3","4","5","6","7","8","9",
        "a","b","c","d","e","f","g","h","i","j","k","l","m",
        "n","o","p","q","r","s","t","u","v","w","x","y","z"); */
    
$length = 4;    // the length of the strings that are saved

for ($x = 1; $x <= $length; $x++)
{
    $pos[$characters[$x]] = 0;
}

$martijn = "goed_bezig";
$handle = fopen("blob4.txt", "w+");
while ($martijn == "goed_bezig")
{
    $string = "";
    for ($x = 1; $x <= $length; $x++)
    {
        $string .= $characters[$pos[$x]];
    }

    if (check_string($pos, $characters))
        fputs($handle, $string."\n");

    increase($pos, $length, $characters);
}
fclose($handle);


zou dat nog efficienter kunnen?

ja ja, ik weet het.. zoals ik het met die while en die die heb opgelost is heel vies,...maarja...ik hoef er niet de schoonheidsprijs mee te verdienen :-)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

marty schreef op 20 June 2003 @ 22:52:
dit is trouwens het script wat ik gemaakt heb:
Wat doet het eigenlijk?

function increase(&$pos, $length, $characters)
--> Waarom doe je niet ook &$characters, scheelt een aantal overbodige kopien, je wijzigt array het verder toch niet.

increase(&$pos, ($length-1), $characters);
--> Weet je zeker dat je hier een recursieve call nodig hebt? Het ziet er meer als een for-loop uit?

else
die("mooi weest");
--> is ook een manier om een recursieve boom te eindigen :o

function check_string($pos, $characters)
--> Ook hier $pos en $character van een &-etje voorzien om kopieren te voorkomen?

foreach ($pos AS $value)
--> Wellicht is een gewone forloop sneller, scheelt je iig het kopieren van alle entries in het array

if (isset($old_value) && strtolower($old_value) == strtolower($value))
--> Waarom old_value niet gewoon een (bogus) begin waarde geven, zodat ie iig altijd bestaat.
Verder zou je stricmp kunnen gebruiken, dat is wellicht vlotter dan deze vergelijking

$characters = array(
"0","1","2","3","4","5","6","7","8","9",
--> Evt kan je daar 1 string van maken en de stringposities direct benaderen (dus alsnog met $characters[x], wat sneller is weet ik niet)

while ($martijn == "goed_bezig")
--> Als je een oneindige loop wilt, doe dan gewoon while(true) dat is een stuk duidelijker :)
zou dat nog efficienter kunnen?
Als je uitlegt wat het doet :o

Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
ehh..dit is wat het doet:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
001a
001b
001c
001d
[....]

Het schrijft dat naar een file weg waarbij alle entries worden weggelaten waar een combinatie van drie dezelfde-opeenvolgende karakters in zit
increase(&$pos, ($length-1), $characters);
--> Weet je zeker dat je hier een recursieve call nodig hebt? Het ziet er meer als een for-loop uit?
Ja, die moet wel echt recursief zijn (zie uitleg die bij de functie staat)
if (isset($old_value) && strtolower($old_value) == strtolower($value))
--> Waarom old_value niet gewoon een (bogus) begin waarde geven, zodat ie iig altijd bestaat.
Verder zou je stricmp kunnen gebruiken, dat is wellicht vlotter dan deze vergelijking
Omdat ik telkens de huidige waarde met de vorige wil bekijken. Als die gelijk is verhoog ik de threshold en als die threshold 3 is, dan weet ik dat er zo'n combinatie van 3 gelijke-opeenvolgende karakters in de string zit en wil ik 'm dus niet wegschrijven in dat bestand
$characters = array(
"0","1","2","3","4","5","6","7","8","9",
--> Evt kan je daar 1 string van maken en de stringposities direct benaderen (dus alsnog met $characters[x], wat sneller is weet ik niet)
Hmm...dat gaat niet werken denk ik. Ik heb die keys namelijk nodig in combinatie met $pos
while ($martijn == "goed_bezig")
--> Als je een oneindige loop wilt, doe dan gewoon while(true) dat is een stuk duidelijker :)
Maar dit is leuker :)

[ Voor 86% gewijzigd door marty op 20-06-2003 23:37 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Goed, ik vond het wel es leuk om te kijken of ik ook zoiets kon maken :)
PHP:
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
function create_strings(&$filepointer, &$characters, $character_count, $current_string="",
      $current_position=0, $current_check_character=-1, $check_character_count=0,
        $length=4, $max_character_count=3)
{
// String is lang genoeg, afdrukken die hap.
        if($current_position >= $length)
        {
                fwrite($filepointer, $current_string);
                fwrite($filepointer, "\n");
        }
// String (verder) maken
        else
        {
// Alle mogelijke chars
                for($i = 0; $i < $character_count; $i++)
                {
// Is dit char niet dezelfde als de vorige?
                        if($i != $current_check_character)
                        {
// Nieuwe aanroep van create_strings, met een nieuwe kans voor X chars op rij
                                create_strings($filepointer, $characters, $character_count, $current_string . $characters[$i],
                                        $current_position + 1, $i, 1, $length, $max_character_count);
                        }
// Is het dezelfde als de vorige maar mag het nog wel, omdat er minder dan max_character_count zijn?
                        elseif($i == $current_check_character && $check_character_count + 1 < $max_character_count)
                        {
// Nieuwe stringsaanroep, maar met doortellen van check_character_count
                                create_strings($filepointer, $characters, $character_count, $current_string . $characters[$i],
                                        $current_position + 1, $i, $check_character_count + 1, $length, $max_character_count);
                        }
                }
        }
}


$characters = array(
        "0","1","2","3","4","5","6","7","8","9",
        "a","b","c","d","e","f","g","h","i","j","k","l","m",
        "n","o","p","q","r","s","t","u","v","w","x","y","z",
        "A","B","C","D","E","F","G","H","I","J","K","L","M",
        "N","O","P","Q","R","S","T","U","V","W","X","Y","Z"); 
$fp = fopen("blob4.txt", "w+");
// Lekker leeg aanroepen, gewoon de defaults nemen
create_strings($fp, $characters , count($characters ));
fclose($fp);

Nou ben ik benieuwd of ie sneller is dan de jouwe (ik geloof dat ie correct is, maar heb hem niet heel goed getest), laat je de testresultaten op jouw doos zien? :)

[ Voor 17% gewijzigd door ACM op 21-06-2003 00:25 ]


Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
doe ik!
mijn eigen brouwsel staat op dit moment nog steeds te pruttelen, dus ik doe 'm morgen.
Ohnee, dan ben ik de hele dag weg. zondag dan.

alvast 1 vraagje trouwens:
PHP:
1
2
                fwrite($filepointer, $current_string);
                fwrite($filepointer, "\n");
waarom doe je dat met twee x het fwrite commando en niet gewoon in ene?
dus
PHP:
1
fwrite($filepointer, $current_string."\n");

[ Voor 51% gewijzigd door marty op 21-06-2003 00:57 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

marty schreef op 21 juni 2003 @ 00:53:
alvast 1 vraagje trouwens:
Mja, dat is een beetje iets dat ik door Java te gebruiken aangeleerd heb, een concattenatie is in principe slomer dan 2x een fwrite, maar het verschil in performance zal wel niet eens meetbaar zijn, misschien is het in php ook wel slomer :)

Bedenk ik me trouwens, mogen combinaties als aAa wel of niet?

[ Voor 9% gewijzigd door ACM op 21-06-2003 03:25 ]


Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Ok, even op een XP1800+ gedraaid:
62^4-62^2*2+62 resultaten (62*62*62*62 combinaties, waarvan xyyy en yyyx niet mogen = 2*62*62, maar dan trek je xxxx er 1x te vaak af dus +61)
= 14768710 resultaten

En zoveel vond mijn applicatietje er ook, dat deed ie in 9 minuten en 10 seconden (= 26852/sec).
Als aAa dus ook niet mag moet ik er even wat meer moeite in steken, maar veel trager zal ie er niet van worden :)

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

PHP:
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
<?
function create_strings(&$filepointer, &$characters, $character_count, &$writebuffer, &$writecounter,
                $current_string="", $current_position=0, $current_check_character=-1, $check_character_count=0,
                &$length, &$max_character_count)
{
        // String is lang genoeg, afdrukken die hap.
        if($current_position == $length)
        {
                $writecounter++;
                $writebuffer .= $current_string . "\n";
                if($writecounter > 8000)
                {
                        fwrite($filepointer, $writebuffer);
                        $writebuffer = "";
                        $writecounter = 0;
                }
        }
        // String (verder) maken
        else
        {
                // Alle mogelijke chars
                for($i = 0; $i < $character_count; $i++)
                {
                        // Is dit char niet dezelfde als de vorige?
                        if($i != $current_check_character)
                        {
                                // Nieuwe aanroep van create_strings, met een nieuwe kans voor X chars op rij
                                create_strings($filepointer, $characters, $character_count, $writebuffer, $writecounter,
                                                $current_string . $characters[$i], $current_position + 1, $i, 1,
                                                $length, $max_character_count);
                        }
                        // Is het dezelfde als de vorige maar mag het nog wel, 
                        //omdat er minder dan max_character_count zijn?
                        elseif($i == $current_check_character && $check_character_count + 1 < $max_character_count)
                        {
                                // Nieuwe stringsaanroep, maar met doortellen van check_character_count
                                create_strings($filepointer, $characters, $character_count, $writebuffer, $writecounter,
                                                $current_string . $characters[$i], $current_position + 1, $i, $check_character_count + 1,
                                                $length, $max_character_count);
                        }
                }
        }
}


$characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
$fp = fopen("blob4.txt", "w+");
// Lekker leeg aanroepen, gewoon de defaults nemen
create_strings($fp, $characters , strlen($characters), $writebuffer, $writecounter, "", 0, -1, 0, $length=4, $max_character_count=3);
fwrite($fp, $writebuffer);
fclose($fp);
?>

Dees doet er trouwens ~66k per seconde op dezelfde doos (verschil is vooral die writebuffer).

En nu hou ik ermee op :P

Mocht aAa ook niet mogen dan kan je de huidige if's vrij eenvoudig uitbreiden zodat ze zowel $i == $current_check_character ALS ($i > 9 && ($i +26 == $current_check_character || $i - 26 == $current_check_character)) checked, oid, moet je er wel passend in kunnen verwerken lijkt me.

[ Voor 3% gewijzigd door ACM op 21-06-2003 12:03 ]


Acties:
  • 0 Henk 'm!

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Allereerst: onwijs koel dat je zo meedenkt! :)

Ik heb zojuist even wat testjes gedaan en mijn vermoeden (kijkende naar jouw code en mijn code) werd bevestigd:
_/-\o_ _/-\o_ _/-\o_
Met jouw code ging het een krappe 2,5x sneller!

Tenminste... ik vermoedde dus wel dat het sneller zou gaan, maar zoveel verschil had ik niet verwacht. Heel erg bedankt: daar leer ik weer veel van. Ik zie de overbodige dingen in m'n eigen code nu ook.

De testresultaten:
me: 22.8440 sec
acm-1e versie: 9.5781 sec
acm-2e versie: 9.3853 sec

waardes zijn gemiddelden over 5 trials, gemeten met een stringlengte van 3 en zonder hoofdletters (had geen zin om lang te wachten :) )
ACM schreef op 21 June 2003 @ 11:52:
Mocht aAa ook niet mogen dan kan je de huidige if's vrij eenvoudig uitbreiden zodat ze zowel $i == $current_check_character ALS ($i > 9 && ($i +26 == $current_check_character || $i - 26 == $current_check_character)) checked, oid, moet je er wel passend in kunnen verwerken lijkt me.
Jup dat is uiteindelijk wel de boedoeling. Ik had eerst eenzelfde constructie als wat je hierboven voorstelt, maar dan met de key uit $characters. Maar die heb ik later vervangen voor die constructie waarbij ik gewoon lomp een strtolower() doe - dat bleek namelijk ook te mogen met een numerieke waarde

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

marty schreef op 22 June 2003 @ 21:07:
De testresultaten:
me: 22.8440 sec
acm-1e versie: 9.5781 sec
acm-2e versie: 9.3853 sec
Apart, bij mij was de tweede versie nog es 2x zo snel als de 1e :)
Maar voor kleinere hoeveelheden woorden maakt het wellicht minder uit, ik had het getest met jouw lengte van 4 :)
Pagina: 1