Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 21
  1. #1

    [C++] Migliorare efficienza codice

    Chiedo consiglio a chi è certamente più esperto di me per migliorare il codice di questa a funzione rendendola il più possibile effeciente in quanto mi ritrovo a doverla richiamare milioni di volte (quindi volendo se ci sono suggerimenti per migliorare anche sotto questo aspetto sono ben accetti). La funzione è la seguente:

    codice:
    #define PI          3.1415926535898
    #define PI_2        1.5707963267949
    
    
    void distance( complex <double> &Z, double &Z_dist, const complex <double> &D )
    {
                
             double theta = 0;
    
    	if( !Z.real() )
    	{
    	     if( Z.imag() > 0 )
    		theta += PI_2;
    
    	      else
    		theta -= PI_2;
    	}
    
    	else if( Z.real() < 0 )
    	       theta += atan( Z.imag() / Z.real() ) + PI;
    
    	else
    	       theta += atan( Z.imag() / Z.real() ) + 2*PI;
    
    	double temp = pow(Z_dist, exponent);
    
    	Z = complex <double> ( temp * cos(theta*exponent) + D.real(),
    			temp * sin(theta*exponent) + D.imag() );
    		
    	Z_dist = sqrt( Z.real()*Z.real() + Z.imag()*Z.imag() );
    }

    Sostituire gli oggetti complex con delle apposite strutture può essere un'idea, ma quanto effettivamente renderebbe più efficiente la funzione? E a discapito di cosa?

    Grazie.

  2. #2
    Se la devi chiamare davvero tante volte potresti dichiararla inline, ma tutto ciò andrebbe a discapito dello spazio occupato dal programma e dal tempo di compilazione. E' sempre e comunque un compromesso.
    An infinite number of monkeys typing into GNU emacs would never make a good program.Linus Torvalds

  3. #3
    Originariamente inviato da EDX
    Se la devi chiamare davvero tante volte potresti dichiararla inline, ma tutto ciò andrebbe a discapito dello spazio occupato dal programma e dal tempo di compilazione. E' sempre e comunque un compromesso.
    Se non sbaglio la keyword inline è fondamentalmente "controllata" dal compilatore, e dubito fortemente che in questo caso la prenderebbe in considerazione.

  4. #4
    Eh si, è a discrezione del compilatore in gran parte, magari hai fortuna.

    In effetti, usare una struttura in stile C per rappresentare i numeri complessi scritta, così, from scratch( )porterebbe un guadagno di prestazioni a mio parere.
    An infinite number of monkeys typing into GNU emacs would never make a good program.Linus Torvalds

  5. #5
    Originariamente inviato da EDX
    In effetti, usare una struttura in stile C per rappresentare i numeri complessi scritta, così, from scratch( )porterebbe un guadagno di prestazioni a mio parere.
    Ne dubito. La classe complex, a livello di dati contenuti, è esattamente equivalente alla struttura che proponi (parte reale, parte complessa); l'overhead dei metodi c'è solo se questi vengono chiamati.

    Io prima di andare a cercare ottimizzazioni strane proverei ad effettuare un profiling e vedere dove sono i "colli di bottiglia" dell'applicazione e/o di questa funzione particolare.
    Tra parentesi, ma il codice in questione (l'ho letto di sfuggita) dovrebbe servire per calcolare la distanza sul piano di Gauss tra due numeri complessi?
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Prova una cosa del genere (codice non testato):
    codice:
    inline int MySign (const double x){
    // just one implementation of the classic sign func
    	return (x > 0) - (x < 0);
    }
    
    inline int MyFunc (const int x){
    // MyFunc (-1) = 1;
    // MyFunc (1) = 2;
    	return (x + 3)/2;
    }
    
    inline complex distanceLowLewel( const complex <double> Z, const complex <double> D )
    {
    	assert (0.0 != Z.real ());   
    	const double theta = atan( Z.imag() / Z.real() ) + MyFunc (MySign (Z.real()))*PI;
    
    	return complex <double> ( temp * cos(theta*exponent) + D.real(),
    		temp * sin(theta*exponent) + D.imag() );
    }
    in cui:
    • Asserisco che Z.real () sia non nullo (visto che devo essere veloce, "delego" al chiamante questo controllo);
    • Elimino l'if utilizzando le funzione MySign e MyFunc;
    • Elimino i riferimenti e "ritorno" al chiamante il risultato;
    • Elimino il calcolo di Z_dist: magari il chiamante non se ne fa nulla, oppure per i fatti suoi gli basta lavorare su x^2+y^2 senza dover scomodare una sqrt.

    i test di velocità falli sulla versione "release" non sulla "debug".

  7. #7
    Originariamente inviato da MItaly
    Ne dubito. La classe complex, a livello di dati contenuti, è esattamente equivalente alla struttura che proponi (parte reale, parte complessa); l'overhead dei metodi c'è solo se questi vengono chiamati.

    Io prima di andare a cercare ottimizzazioni strane proverei ad effettuare un profiling e vedere dove sono i "colli di bottiglia" dell'applicazione e/o di questa funzione particolare.
    Tra parentesi, ma il codice in questione (l'ho letto di sfuggita) dovrebbe servire per calcolare la distanza sul piano di Gauss tra due numeri complessi?
    Calcola la distanza dall'origine in un piano di Gauss, solo che il calcolo lo effettua attraverso una rappresentazione polare, ed è proprio questo il vero limite dell'applicazione, bisognerebbe utilizzare un sistema di coordinate cartesiane.

    Si, non ci avevo pensato di andare a vedere dove sono effettivamente i colli di bottiglia, forse perchè pur sapendo cosa sono non saprei come fare, potresti spiegarmi?

    In ogni caso testerò anche una funzione del tutto equivalente ma che utilizza strutture piuttosto che la classe complex, che ad intuito sembra davvero essere dispendiosa e sintatticamente decisamente poco piacevole .

  8. #8

    in cui:
    • Asserisco che Z.real () sia non nullo (visto che devo essere veloce, "delego" al chiamante questo controllo);
    • Elimino l'if utilizzando le funzione MySign e MyFunc;
    • Elimino i riferimenti e "ritorno" al chiamante il risultato;
    • Elimino il calcolo di Z_dist: magari il chiamante non se ne fa nulla, oppure per i fatti suoi gli basta lavorare su x^2+y^2 senza dover scomodare una sqrt.

    i test di velocità falli sulla versione "release" non sulla "debug".

    Perdona la mia ignoranza ma delle inline sono realmente meno dispendiose rispetto ai controlli if?

    Il calcolo di Z_dist è effettivamente necessario anche se si potrebbe eliminare facilmente la radice quadrata in quanto bisogna confrontare il risultato successivamente.

  9. #9
    EDIT: mi correggo non è possibile eliminare la radice quadrata...

  10. #10
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    la butto li, (vuoi vede che vinco?) il cross product e poi un bel dot
    Per gli Spartani e Sparta usa spartan Il mio github

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.