Newsgroup: it.comp.www.php
Titolo: Considerazioni sulle prestazioni

Con un semplice time() un po' modificato calcolo il tempo di esecuzione 
di un mio script. Si attesta sui 0.005 secondi circa.
Aggiungendo questo codice:
$col = 0;
       $j=0;
       $elementi[0] = $elementi[1] = $elementi[2] = 0;
       while ($elementi[0] + $elementi[1] + $elementi[2] < $totalemarche){
         $elementi[0] = $elementi[0] + 1;
         if ($elementi[0] + $elementi[1] + $elementi[2] < $totalemarche)
           $elementi[1] = $elementi[1] + 1;
         if ($elementi[0] + $elementi[1] + $elementi[2] < $totalemarche)
           $elementi[2] = $elementi[2] + 1;
       }
       echo '<ul id="all">';
       while ($col < 3 && $elementi[$col] > 0){
         echo '<ul class="sx">';
         for ($i = 0; $i < $elementi[$col]; $i++){
           $marcaurl = urlencode($tutti[$j]);
           echo "<li><a href=?p=brand&nomemarca=". 
$marcaurl.">".$tutti[$j]."</a></li>
           ";
           $j++;
         }
         echo '</ul>
         ';
         $col++;
       }
E' un frammento che divide un array in 3 colonne e lo stampa. Passo a 
una media di 0.05 secondi, ovvero 10 volte tanto.
Non eseguo ulteriori query, $tutti è un array di 87 elementi e non mi 
sembra di fare funzioni particolarmente complicate (il while in alto 
sono addizioni e confronti, quello sotto solo un echo).
Come si spiega un aumento di questo tipo? Ovvio, la differenza non è tra 
5 e 50 secondi, ma vorrei comunque capire il perchè di questo.
Grazie mille


Tutte le funzioni di output sono lente - prova a vedere se il collo di
bottiglia è quello utilizzando funzioni di buffering.
Anche lo urlencode() non è certo un aiuto alla performance. Se tieni
conto del fatto che nella seconda parte hai tre cicli innestati
(while, for e urlencode(che è implementato ciclando i caratteri della
stringa passata come parametro) hai una complessità decisamente alta.
Vedendo il tuo codice, potresti portare fuori dal while lo urlencode,
precalcolando i valori di $tutti[].
Ciao!

 precalcolando i valori di $tutti[].
Ho provato questo, con un foreach prima di iniziare il ciclo, ma 
suppongo che, prima o dopo, questo ciclo con la urlencode me lo devo 
fare, e infatti non è cambiato niente in termini di tempo.
Ti dirò di più: eliminando totalmente la urlencode (e quindi sballando 
tutti i link) i tempi rimangono più o meno quelli.
E' dunque l'output a richiedere così tanto tempo? In realtà il resto 
dello script (senza il ciclo che ho postato) è anche quello tempestato 
di echo, anche quelli urlencodati: è una lista di marche, la prima parte 
dello script le stampa tutte in ordine alfabetico, in div differenti. La 
seconda parte (quello che ho postato) le ristampa tutte in un unico div.
In pratica la quantità di echo più o meno si raddoppia, ma il tempo di 
esecuzione decuplica.
Puoi spiegarmi come posso provare a usare un buffer?
Grazie

 Puoi spiegarmi come posso provare a usare un buffer?
Puoi provare ad usare le funzioni php ob_XXX  (ob_start(), ob_flush(),
etc) oppure concatenare le stringhe a mano e fare un solo echo (cosa
che sconsiglio, visto che la concatenazione di stringhe lunghe è
comunque un'operazione abbastanza pesante).
Comunque se vuoi essere sicuro che siano gli echo, per me basta che li
commenti tutti e vedi se il tempo si riduce di molto oppure no.
Ciao!

 5 e 50 secondi, ma vorrei comunque capire il perchè di questo.
anche io porterei fuori dallo while la parte con gli urlencode:
for ($i = 0; $i < count($tutti); $i++)
$tutti2[$i]=urlencode($tutti[$i]);
sempre che il numero di urlencode fatti in questo modo sia minore di
quelli fatti nell'altro

5 e 50 secondi, ma vorrei comunque capire il perchè di questo.
O e' il while e hai una tonnellata di marche, o e' l'output. O forse stai
cronometrando anche il tempo di INVIO dell'output.
Leonardo
-- 
And where the black and corkscrew towers climb,
Lost and athirst the ragged pack abides,
Old as the aeons, trapped in tombs of time,
Sailing the tortuous temporal tides

            ";
Se utilizzi i doppi apici php farà il parsing della stringa per 
interpretare quello contenuto all'interno... se le variabili le concateni 
come stai facendo ora, utilizza l'apice singolo, altrimenti tanto vale 
non utilizzare la concatenazione e inserire tutto dentro i doppi apici.
In questo caso devi provare tutti e due i modi per vedere quale è il più 
conveniente.

 comunque un'operazione abbastanza pesante).
Grazie, magari mi vado a vedere le funzioni su ob_*.

 quelli fatti nell'altro
Ti rispondo come ho risposto a fmassei (ovvero che forse non ho capito 
io :D) : la quantità di urlencode da eseguire è per forza la stessa, o 
lo faccio prima o lo faccio dopo...

 
Provato col tuo script: prima del print: 0.005
dopo il print: 0.04 o giù di li
Quindi è l'output.... quello che non capisco però è che come ho già 
detto più volte l'output raddoppia semplicemente; prima lo stampo diviso 
per iniziale, poi tutto insieme, ma sono sempre e comunque 87 steps...

 non utilizzare la concatenazione e inserire tutto dentro i doppi apici.
Ti ringrazio, hai ragione. Quando pulirò il tutto vedrò di farci caso :)


E' ovvio che l'output ci metta molto ad essere eseguito, ma non è un
ritardo dovuto al php, ma al sistema sottostante: se esegui il php
tramite un webserver, ad esempio, hai il tempo di connessione del/i
socket, la trasmissione degli header http etc.etc. che di certo non
sono poco. Pensando a tutto questo a volte mi stupisco di quanto sia
veloce :) Prova ad esempio ad eseguire lo script come CLI invece che
sul webserver e vedrai che l'incremento della velocità sarà notevole.
Comunque c'è da dire che il ritardo sull'output nelle pagine non è
lineare: c'è una quantità di tempo fissa che non puoi tralasciare,
passata la quale l'output ha le stesse (o quasi) performances di uno
script locale a causa dei buffer interni.
Ciao!

per iniziale, poi tutto insieme, ma sono sempre e comunque 87 steps...
Data la struttura del buffering di webserver e strato di rete, potrebbe
darsi che il primo output ce la faccia a stare nei buffer, e quindi non
rallenti; il secondo riempie il buffer e forza un "flush", introducendo
tittedentratto un proporzionalmente enorme tempo di I/O.
Per verifica, potresti mettere anziche'
	print $output
un
	print str_pad(" ", N);
per mandare in output N spazi. Parti da N=32 e lo raddoppi finche' vedi
che il tempo passa da 0.005 a 0.04 e a quel punto puoi raffinare N fino
a vedere "SE" esiste un N tale che
	print str_pad(" ", N)	= tempo 0.005
	print str_pad(" ", N+1)	= tempo 0.04
Se esiste, N o N+1 e' la dimensione equivalente del buffer di output su
QUELLA macchina (altre macchine potrebbero avercelo diverso).
Questo se non ci sono ulteriori complicazioni dovute alla compressione,
perche' N spazi si comprimono benone ecc. ecc. .
===
Dal punto di vista pratico, pero', la tua domanda dovrebbe essere:
   "C'e' modo di mandare lo stesso output in 0.005 invece che 0.04?"
e la mia risposta e':
   "Quasi certamente NO; ma vai magari alla voce ob_gzhandler".


 a vedere "SE" esiste un N tale che
Grazie mille, molto interessante davvero :) Proverò