Ottimizzazione codice, vantaggi poo

di il
60 risposte

Ottimizzazione codice, vantaggi poo

So già che la domanda non risulterà molto chiara, ma sono confuso su alcuni concetti di POO e quindi vi chiedo: ci possono essere dei vantaggi ad usare le classi in c++, nel senso, ti potrebbero permettere di velocizzare un programma?
Esempio banale:
un vettore<vettore<int> >A
e una classe Gruppi{vettore<int> B} (e nel main avrò un vettore<Gruppi*>A)
Tutte e due hanno dei metodi di inserimento, ordinamento, cancellazione e ricerca, e hanno lo stesso output, avrò dei benefici usando le classi? In che modo potrei averne? Pacca sulla spalla e senso di pietà nei miei confronti ?

60 Risposte

  • Re: Ottimizzazione codice, vantaggi poo

    La classi STL sono fatti da persone molto esperte e generalemente e quasi sempre usare quelle classi è molto meglio che reinventare la ruota. Nelle classi STL fanno parte molti contenitori trai quali anche i vector, quindi la mia risposta è: Usa sempre STL finchè puoi.

    p.s.: il titolo non centra col discorso.
  • Re: Ottimizzazione codice, vantaggi poo

    Potresti fare un esempio? quelle due strutture che ho messo valgono come esempio o sono praticamente la stessa cosa?
  • Re: Ottimizzazione codice, vantaggi poo

    Strutture a casa mia sono le struct, qui si parla di classi.
    vector<vector<int> >A
    è un vettore di vettori (chiamato anche matrice)
    Gruppi{vector<int> B}
    è una classe che contiene una variabile membro di tipo vector
    vector<Gruppi*>A
    è un vettore di puntatori alla classe B.
    Nessuna è equivalente.
  • Re: Ottimizzazione codice, vantaggi poo

    Siccome devo cercare di ottimizzare un programma mi chiedevo come fare. Avevo capito che usando dei metodi di poo si poteva rendere un codice più performante, praticamente ho una map <int,int> che contiene come primario delle hashkey e come secondario l'indice di dove queste sono salvate e una classe vector<Gruppi*>A, con Gruppi{vector<int> B}, che mi salva le varie hashkey dove è indicato dall'indice. Pensavo di avere dei miglioramente rispetto ad un vettore<vettore<int>> ma praticamente impiegano lo stesso tempo.
  • Re: Ottimizzazione codice, vantaggi poo

    Cerca di imparare le funzioni dei header algorithm e functional.
    Poi senza un stralcio di codice stiamo solo supponendo.
    un vector<shared_ptr<Gruppi>> è più efficiente di un vector<Gruppi *> in qunato non ti lascia sbagliare e le allocazioni sono reference_counted.
  • Re: Ottimizzazione codice, vantaggi poo

    Ok
    class Gruppi
    {
          vector<int> hashGruppi;
    public:
        Gruppi();
        Gruppi(int& hkparola)
        {
            hashGruppi.push_back(hkparola);
        };
        ~Gruppi();
        inline int hashGruppiSize()    {        return hashGruppi.size();    }
        inline void inserisci(int& hkparola)    {        hashGruppi.push_back(hkparola);    }
        inline void svuota()    {        hashGruppi.clear();    }
        inline vector<int> ritornaVettore()    {        return hashGruppi;    }
    	
    	inline void elimina(int& hkparola)    {
            for(vector<int>::iterator posIt6 = hashGruppi.begin(); posIt6 != hashGruppi.end(); ++posIt6)        {
                if(*posIt6==hkparola)            {
                    *posIt6=hashGruppi.back();
                    hashGruppi.back()=hkparola;
                    hashGruppi.pop_back();
                    break;
                }
            }
        }
        
    };
    
    
    inline int funzHash(string& parolaHash)
    {
        int h = 5381;
        for (int i=0; i<parolaHash.size(); ++i)    {
            h = h * 33 + parolaHash[i];
        }
        h=abs(h);
        return h;
    }
    
    int main()
    {
    
        vector<Gruppi*> vecGruppi;
        vector<int> lettereGruppo;
        map<int,int> keyGruppi;/// una map di <hash_key, group_id>
        string input,parola,parola2;
        int dimCoda = 0,b = 0;
        char s;
    
        while(input != "<END>")    {
            getline(cin, input);
            stringstream ssin(input);
            s=0,parola="",parola2="";
            ssin >> s;
    
            if (s == 'i')        {
                lettereGruppo.clear();
                vecGruppi.clear();
                keyGruppi.clear();
                ssin >> dimCoda>> b;
            }
            else if (s == 'e')        {
                int x=0;
                lettereGruppo.resize(dimCoda);
                while(x < dimCoda)            {
                    ssin >> parola;
                    int hk=funzHash(parola);
                    keyGruppi.insert(pair<int,int>(hk,x));
                    lettereGruppo[x]=parola.size();
                    vecGruppi.push_back(new Gruppi(hk));
                    x++;
                }
    
            }
    
            else if (s == 'm' || s == 'u' || s == 's')        {
                ssin >> parola >> parola2;
                int hk1=funzHash(parola),hk2=funzHash(parola2);
                map<int,int>::iterator it;
                map<int,int>::iterator it2;
                int grupId1=0,grupId2=0;
                bool ver0=false,ver1=false;
                it=keyGruppi.find(hk1);
                if(it != keyGruppi.end())            {
                    grupId1=it->second;
                    ver0=true;
                }
    
                if(s == 'm' || s == 'u')            {
                    it2=keyGruppi.find(hk2);
                    if(it2 != keyGruppi.end())                {
                        grupId2=it2->second;
                        ver1=true;
                    }
                }
    
                if(ver0 && s == 's')            { //qui devo stampare il totale di parola e lettere del vettore di parola1
                    cout<<vecGruppi[grupId1]->hashGruppiSize()<<" "<<lettereGruppo[grupId1]<<endl;
                }
    
    
                if(ver1 && ver0 && grupId2!=grupId1)            {
                    if(s == 'm')                { //qui devo spostare parola1 dal vettore di parola1 al vettore di parola2
                        vecGruppi[grupId1]->elimina(hk1);
                        vecGruppi[grupId2]->inserisci(hk1);
                        it->second=grupId2;
                        lettereGruppo[grupId1]-=parola.size();
                        lettereGruppo[grupId2]+=parola.size();
                    }
    
                    else if(s == 'u' )                { //qui devo unire il vettore di parola1 col vettore di parola2
                        map<int,int>::iterator it3;
                        vector<int> temp=vecGruppi[grupId1]->ritornaVettore();
                        for(vector<int>::iterator posIt3 = temp.begin(); posIt3 != temp.end(); ++posIt3)                    {
                            it3=keyGruppi.find(*posIt3);
                            it3->second=it2->second;
                            vecGruppi[grupId2]->inserisci(*posIt3);
                        }
                        vecGruppi[grupId1]->svuota();
                        lettereGruppo[grupId2]+=lettereGruppo[grupId1];
                        lettereGruppo[grupId1]=0;
                    }
                }
            }///else if (s == 'm' || s == 'u' || s == 's')
        }///fine while(input != "<END>")
        return 0;
    Mi chiedevo come renderlo più performante, deve essere veloce almeno il doppio di quanto lo è ora
  • Re: Ottimizzazione codice, vantaggi poo

    inline void elimina(int& hkparola)    {
            for(vector<int>::iterator posIt6 = hashGruppi.begin(); posIt6 != hashGruppi.end(); ++posIt6)        {
                if(*posIt6==hkparola)            {
                    *posIt6=hashGruppi.back();
                    hashGruppi.back()=hkparola;
                    hashGruppi.pop_back();
                    break;
                }
            }
        }
    trasformabile in
    
    #include <algorithm>
    .......................
    
    
    inline void elimina(int& hkparola)    {
            hashGruppi.erase(std::remove(hashGruppi.begin(),hashGruppi.end(),hkParola),hashGruppi.end());
            }
        }
    Attenzione perche sto metodo ti rimuove TUTTI gli hkparola trovati.

    Questo
    inline vector<int> ritornaVettore()    {        return hashGruppi;    }
    Ti serve veramente una copia? Non basta un reference?

    Il resto non l'ho visto perchè è tardi ma credo che devi vedere dov'è che perdi più tempo. Ne parliamo domani.
  • Re: Ottimizzazione codice, vantaggi poo

    Una piccola cosa
    lettereGruppo.resize(dimCoda);
    Ma se dimCoda è zero qui distruggi tutto.

    Altro accorgimento: Usa un set invece che un vettore la ricerca è log(n), oppure meglio se il compilatore lo permette un unordered_set con ricerca log(1) caso medio
  • Re: Ottimizzazione codice, vantaggi poo

    Le hkparole sono uniche, non ci sono doppioni. (Avevo usato quel metodo per swappare la parola all'ultimo posto e non far riscorrere il vettore quando la cancellavo).

    Si qui
    inline vector<int> ritornaVettore()    { return hashGruppi;}
    infatti non volevo fare una copia, ma era protected.

    EDIT:
    Purtroppo unorder_map non posso, il set l'ho provato, avevo provato anche con map, mi garantivano una maggiore velocità di ricerca, ma perdevano troppo tempo nell'inserimento e cancellazione, è risultato più veloce un vettore disordinato che itera finchè non trovaa l'elemento(ovviamente nel caso che io abbia un indice che mi dica in che vettore cercare e non debba scorrerli tutti uno ad uno, in quel caso non conveniva).
  • Re: Ottimizzazione codice, vantaggi poo

    for(vector<int>::iterator posIt3 = temp.begin(); posIt3 != temp.end(); ++posIt3)                    {
                            it3=keyGruppi.find(*posIt3);
                            it3->second=it2->second;
                            vecGruppi[grupId2]->inserisci(*posIt3);
                        }
    Qui vedo che stai unendo i due vettori. Ma per forza dei farlo int x int? Non puoi copiare e basta un vettore in un altro? Prima fai un reserve e poi un copy.

    Mi servono dati di input certi per valutare i tempi di esecuzione perche non comprendo cosa fa il programma.

    Prova poi a vedere lo schema in fondo a questa pagina e vedi se il tuo raggionamento ti porta ad usare li stessi contenitori di adesso applicando lo schema

  • Re: Ottimizzazione codice, vantaggi poo

    Faccio in quel modo perchè quando unisco due gruppi, devo aggiornare l'indice, quindi tutte le hashkey del gruppo1(che finiranno nel gruppoX), le devo trovare nella map che contiene <hashkey,gruppo_id> e gli aggiorno il gruppo di destinazione, purtroppo devo fare cosi.


    Poi a quanto ho capito c'è tutto un concetto di memoria dinamica, heap and stack, che mi potrebbe velocizzare l'esecuzione del programma in maniera considerevole, ma sto cercando di capire come modificare il mio codice.
  • Re: Ottimizzazione codice, vantaggi poo

    Che ne dici di creare una classe dove una parola tiene conto del proprio hash e del proprio gruppo di appartenenza? Così sembra che il lavoro si semplifica ulteriormente. Pensaci.
  • Re: Ottimizzazione codice, vantaggi poo

    Ecco una cosa del genere
    class Parola
    {
    	public:
    		Parola(const std::string & str = "")
    			: m_string(str)
    			, m_hash(funzHash(str))
    			, m_ID(-1)
    		{
    
    		};
    		const int GetHash() const { return m_hash; };
    		const int GetGroupID() const { return m_ID; };
    		const void SetGroupID(const int & groupID){ m_ID = groupID; };
    	private:
    		const int funzHash(const std::string & parolaHash)
    		{
    			int h = 5381;
    			const size_t size = parolaHash.size();
    			for (size_t i = 0; i < size; ++i)    
    			{
    				h = h * 33 + parolaHash[i];
    			}
    			h = abs(h);
    			return h;
    		}
    	private:
    		std::string m_string;
    		int m_hash;
    		int m_ID;
    };
  • Re: Ottimizzazione codice, vantaggi poo

    Quindi mi devo creare sempre una lista di Parola?
    Quando ricevo in input una parola, scorro questa lista<Parola> finchè parolaInput ed m_string non sono uguali, se uguali vedo che hash ha e il grup_id. Se è questo che intendi(ma non penso), perchè è migliore rispetto a map<hahskey,grup_id>?
Devi accedere o registrarti per scrivere nel forum
60 risposte