Newsgroup: it.comp.lang.delphi
Titolo: Lentezza nell'esecuzione

Ho fatto un programmino di prova che fa un'elaborazione di un array
Il nocciolo della procedura sono 4 for innestati di 320,240,10 e 36 cicli
per un totale di 27.648.000 cicli più interni in cui faccio 3 if con 3 Inc o
Dec
Il tutto in esecuzione su un proc a 900MHz ci mette la bellezza di
10secondi!
A me servirebbe fosse quasi realtime ma mi accontenterei di un paio di
secondi
C'è qualche ottimizzazione del compilatore di Delphi6 che possa darmi una
mano o forse chiedo troppo e devo migrare a qualche altro linguaggio?
--
_________________________________________
Edmondo Di Tucci snar...@Ttin.it
guarda i miei lavori su: 
www.powernetsi.it/edmondo

"Edmondo Di Tucci" <snar...@Ttin.it> ha scritto nel messaggio
news:ThdLa.127632$Ny5.3...@twister2.libero.it...

Posta il codice che lo ottimizziamo insieme.
Ciao
Giorgio

Codice postato! E mo?
function CentroPalla(Image: TImageData; var x0,y0,r0,percentuale: integer):
Boolean;
const
 rmin: integer=7;
 rmax: integer=15;
 punti: integer=36;
var
 x,y,r,angolo,indiceMax,indiceTemp: integer;
 seno,coseno: extended;
begin
indiceMax:=0;
for x:=rmax to 319-rmax do
for y:=rmax to 239-rmax do
for r:=rmin to rmax do
 begin
  indiceTemp:=0;
  for angolo:=0 to punti-1 do
   begin
    sincos(angolo*2*pi/punti,seno,coseno);
    if Image[x+Trunc(r*coseno),y+Trunc(r*seno)]=255 then Inc(indiceTemp)
     else Dec(indiceTemp);
    if Image[x+Trunc((r-3)*coseno),y+Trunc((r-3)*seno)]=0 then
Inc(indiceTemp)
     else Dec(indiceTemp);
    if Image[x+Trunc((r+3)*coseno),y+Trunc((r+3)*seno)]=0 then
Inc(indiceTemp)
     else Dec(indiceTemp);
   end;
  if indiceTemp>indiceMax then
   begin
    x0:=x; y0:=y; r0:=r; indiceMax:=indiceTemp;
   end;
 end;
percentuale:=Trunc(100*(indiceMax/(punti*3)));
CentroPalla:=percentuale>75;
end;


"Edmondo Di Tucci" <snar...@Ttin.it> ha scritto nel messaggio
news:NFdLa.128963$lK4.3...@twister1.libero.it...

Alla faccia di solo 3 inc o dec a seconda dell'if!!!
Ci sono oltre 20 calcoli in virgola mobile da fare per 27.5 milioni di
volte!!!
Se te lo fai tutto in assembly forse forse arrivi a 2-3sec...

ho provato a scrivere un codice, spero sia corretto per la funzione che ti 
serve, quello che ho fatto creare dei vettori con all'interno i calcoli già 
eseguiti che poi verranno utilizzati all'interno del ciclo for.
Dato che non conosco TImageData mi sono creato un vettore a caso.
Se ho fatto tutto in modo corretto dovrebbe essere circa 8 volte piu' 
veloce, controlla bene i calcoli, spero di averli capiti bene.
Ricordati che quello che ottimizza non è mai il compilatore, ma le 
istruzioni che scrivi tu (poi che il compilatore possa dare una mano.....).
type TImageData = Array[1..700,1..700] of integer;
Var a : TimageData;
function CentroPalla(Var Image: TImageData; var x0,y0,r0,percentuale: 
integer):
Boolean;
const
 rmin: integer=7;
 rmax: integer=15;
 punti: integer=36;
type
 vet_punti= array[0..35] of real;
 vet_r = array[7..15] of integer;
var
 x,y,r,angolo,indiceMax,indiceTemp: integer;
// seno,coseno: single;
 v_punti, v_sen,v_cos : vet_punti;
 v_r_cos,v_r1_cos,v_r2_cos : vet_r;
 v_r_sin,v_r1_sin,v_r2_sin : vet_r;
begin
for angolo := 0 to punti-1 do // primo vettore di calcoli
begin
  v_punti[angolo] := angolo*2*pi/punti;
  v_sen[angolo] := sin(v_punti[angolo]);
  v_cos[angolo] := cos(v_punti[angolo]);
end;
for r := rmin to rmax do // secondo vettore di calcoli
begin
  v_r_cos[r] := Trunc(r*v_cos[r]);
  v_r1_cos[r] := Trunc((r-3)*v_cos[r]);
  v_r2_cos[r] := Trunc((r+3)*v_cos[r]);
  v_r_sin[r] := Trunc(r*v_sen[r]);
  v_r1_sin[r] := Trunc((r-3)*v_sen[r]);
  v_r2_sin[r] := Trunc((r+3)*v_sen[r]);
end;
indiceMax:=0;
for x:=rmax to 319-rmax do
for y:=rmax to 239-rmax do
for r:=rmin to rmax do
 begin
  indiceTemp:=0;
  for angolo:=0 to punti-1 do
   begin
//    sincos(angolo*2*pi/punti,seno,coseno);
    if Image[x+v_r_cos[r],y+v_r_sin[r]]=255 then Inc(indiceTemp)
    else Dec(indiceTemp);
    if Image[x+v_r1_cos[r],y+v_r1_sin[r]]=0 then Inc(indiceTemp)
    else Dec(indiceTemp);
    if Image[x+v_r2_cos[r],y+v_r2_sin[r]]=0 then Inc(indiceTemp)
    else Dec(indiceTemp);
   end;
  if indiceTemp>indiceMax then
   begin
    x0:=x; y0:=y; r0:=r; indiceMax:=indiceTemp;
   end;
 end;
percentuale:=Trunc(100*(indiceMax/(punti*3)));
CentroPalla:=percentuale>75;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
var
    x,y,r,p : Integer;
begin
 CentroPalla(a,x,y,r,p);
end;
-- 
-----------------------------
Per rispondere in privato togliere 1975
Using M2, Opera's revolutionary e-mail client: 
http://www.opera.com/m2/

 Se te lo fai tutto in assembly forse forse arrivi a 2-3sec...
2-3 secoli a programmare
Ho riprovato con i consigli corretti di Ca75 (dovevano perň essere matrici e
non
vettori) e ci ho guadagnato un ordine di grandezza
Mo ci metto poco meno di 2 secondi
Ho provato pure ad usare i tipi strettamente necessari al posto degli interi
ma non migliora affatto
Vi posto il codice
function CentroPalla(Image: TImageData; var x0,y0,r0,percentuale: integer):
Boolean;
const
 rmin: integer=7;
 rmax: integer=15;
 punti: integer=36;
type
  vet_aux=array[7..15] of array[0..36] of integer; //sistema con
rmin,rmax,punti
var
 x,y,r,angolo,indiceMax,indiceTemp: integer;
 seno,coseno: extended;
 xB,xI,xE,yB,yI,yE: vet_aux;
begin
for r:=rmin to rmax do
 for angolo:=0 to punti-1 do
  begin
   sincos(angolo*2*pi/punti,seno,coseno);
   xB[r,angolo]:=Trunc(r*coseno);
   xI[r,angolo]:=Trunc((r-3)*coseno);
   xE[r,angolo]:=Trunc((r+3)*coseno);
   yB[r,angolo]:=Trunc(r*seno);
   yI[r,angolo]:=Trunc((r-3)*seno);
   yE[r,angolo]:=Trunc((r+3)*seno);
  end;
indiceMax:=0;
for x:=rmax to 319-rmax do
for y:=rmax to 239-rmax do
for r:=rmin to rmax do
 begin
  indiceTemp:=0;
  for angolo:=0 to punti-1 do
   begin
    if Image[x+xB[r,angolo],y+yB[r,angolo]]=255 then Inc(indiceTemp)
     else Dec(indiceTemp);
    if Image[x+xI[r,angolo],y+yI[r,angolo]]=0 then Inc(indiceTemp)
     else Dec(indiceTemp);
    if Image[x+xE[r,angolo],y+yE[r,angolo]]=0 then Inc(indiceTemp)
     else Dec(indiceTemp);
   end;
  if indiceTemp>indiceMax then
   begin
    x0:=x; y0:=y; r0:=r; indiceMax:=indiceTemp;
   end;
 end;
percentuale:=Trunc(100*(indiceMax/(punti*3)));
CentroPalla:=percentuale>75;
end;
--
_________________________________________
Edmondo Di Tucci snar...@Ttin.it
guarda i miei lavori su: 
www.powernetsi.it/edmondo
"Balbar" <...@...> ha scritto nel messaggio
news:01eLa.7020$de....@news.edisontel.com...

 2-3 secoli a programmare
prova a dare un'occhiata a questo link:
http://www.optimalcode.com/general.htm#style
Ci sono delle ottimizzazioni sui tipi che usi e sui cicli for che potresti
provare. A detta dell'autore del sito le ottimizzazioni del codice Delphi (a
discapito della leggibilità, tuttavia) sono al massimo inferiori del 10%
come prestazioni rispetto alle relative controparti assembler.
Ciao
Antonio

 Codice postato! E mo?
E mo, perché non incominci a precalcolare i seni ed i coseni?
*SOLO UN ESMPIO*:
var Seni : array[ 0..360 ] of Extended;
      Coseni : array[ 0..360 ] of Extended;
procedure Precalcola;
var Val_Index : Integer;
begin
  for Val_Index := 0 to 360 do
  begin
     Seni[ Val_Index ] := sin( Val_Index );
     Coseni[ Val_Index ] := cos( Val_Index );
  end;
end;
Poi richiami "Precalcola" all'inizio del programma, dopodiché tieni in
memoria gli array, potendo scrivere due funzioni:
function FastSin( X : Integer ) : Extended;
begin
   Result := Seni[ X ];
end;
function FastCos( X : Integer ) : Extended;
begin
   Result := Coseni[ Index ];
end;
Queste funzioni non tengono conto che se il numero di gradi è
superiore, deve essere semplificato.
Ciao
Andrea


inc e dec si, ma tutte le operazioni del tipo "angolo*2*pi/punti" o
"r*coseno" ?
Queste si sono in virgola mobile e le fai lo stesso numero di volte degli
inc o dec.

o forse chiedo troppo e devo migrare a qualche altro linguaggio?
Dopo aver ottimizzato sulla guisa del thread il tuo codice, migra la stessa
routine in un altro linguaggio, e fai i confronti, poi facci sapere il
risultato che sono molto curioso, anche se credo che non cambiera' di molto.
-- 
Morde. 
(morde at programmer dot net)

 risultato che sono molto curioso, anche se credo che non cambiera' di
molto.
Fatto!
Ho riscritto tutto l'ambaradan in Builder5 e invece di metterci 4s (tutte le
procedure che chiamo e non solo l'incriminata) ce ne mette 3s
Ho provato anche le singole procedure e in definitiva il codice è mediamente
più veloce del 25%
Non male anche se preferisco restare con Delphi per cui ho pure la licenza


Non male anche se preferisco restare con Delphi per cui ho pure la licenza
Fai bene :)


 fermano qui.
Sta dritta del Builder che è più veloce me l'ha data un amico (che mi ha
pure dato il Builder per le mie prove) che sviluppa il software per
PhotoCity.
Il programmino che hanno ridimensiona le foto in jpeg a seconda della
dimensione originale e di quella di stampa Se è troppo grande per il formato
scelto la rimpicciolisce così da non dover mandare file inutilmente grandi
perdendo ore di connessione
Loro prima di imbarcarsi nella cosa provarono vari ambienti di sviluppo e
notarono che l'algoritmo di riconversione impiegava tempi molto diversi a
seconda dell'ambiente usato
Nell'ordine Vbasic, Delphi, VisualC, Builder, da qualche secondo a meno di
un quarto Da non credere!
Evidentemente è dovuto a delle ottimizzazioni che i compilatori fanno
Daltronde Delphi per il build di un progetto di qaulche migliaio di righe ci
mette... boh, pochissimo che neanche me ne accorgo mentre Builder anche per
poche centinaia ci mette qualche secondo Un motivo ci sarà!
