Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza
Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza
Motorola edge 70 porta il concetto di smartphone ultrasottile su un terreno più concreto e accessibile: abbina uno spessore sotto i 6 mm a una batteria di capacità relativamente elevata, un display pOLED da 6,7 pollici e un comparto fotografico triplo da 50 MP. Non punta ai record di potenza, ma si configura come alternativa più pragmatica rispetto ai modelli sottili più costosi di Samsung e Apple
Display, mini PC, periferiche e networking: le novità ASUS al CES 2026
Display, mini PC, periferiche e networking: le novità ASUS al CES 2026
Sono molte le novità che ASUS ha scelto di presentare al CES 2026 di Las Vegas, partendo da una gamma di soluzioni NUC con varie opzioni di processore passando sino agli schermi gaming con tecnologia OLED. Il tutto senza dimenticare le periferiche di input della gamma ROG e le soluzioni legate alla connettività domestica
Le novità ASUS per il 2026 nel settore dei PC desktop
Le novità ASUS per il 2026 nel settore dei PC desktop
Molte le novità anticipate da ASUS per il 2026 al CES di Las Vegas: da schede madri per processori AMD Ryzen top di gamma a chassis e ventole, passando per i kit di raffreddamento all in one integrati sino a una nuova scheda video GeForce RTX 5090. In sottofondo il tema dell'intelligenza artificiale con una workstation molto potente per installazioni non in datacenter
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 26-06-2013, 12:54   #1
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
[C++ / std:sort()]

Buondì

La funzione sort() durante il processo di ordinamento, mi modifica gli elementi. In particolare, svuota dei vettori.

Il mio intento è ordinare un vector<> di oggetti di tipo:
Codice:
template<typename T>
class geneBase
{
...
	bool operator<(geneBase b)	{return(fitness < b.GetFitness());}
...
	vector<T> *code;
};
Dove ho definito l'operatore < utilizzato da sort().

In un'altra classe definisco il vettore di questi elementi e utilizzo sort():

Codice:
template <typename T>
class populationBase
{
...
	vector<geneBase<T>> population;
...
};
Quindi nel file .cpp:
Codice:
std::sort(population.begin(), population.end());
Tutti i vettori vector<T> negli elementi geneBase<T> poi risultano vuoti...
non devo usare un puntatore nella dichiarazione?
grazie dell'aiuto.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 26-06-2013, 15:17   #2
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Buondì

La funzione sort() durante il processo di ordinamento, mi modifica gli elementi. In particolare, svuota dei vettori.

Il mio intento è ordinare un vector<> di oggetti di tipo:
Codice:
template<typename T>
class geneBase
{
...
	bool operator<(geneBase b)	{return(fitness < b.GetFitness());}
...
	vector<T> *code;
};
Dove ho definito l'operatore < utilizzato da sort().

In un'altra classe definisco il vettore di questi elementi e utilizzo sort():

Codice:
template <typename T>
class populationBase
{
...
	vector<geneBase<T>> population;
...
};
Quindi nel file .cpp:
Codice:
std::sort(population.begin(), population.end());
Tutti i vettori vector<T> negli elementi geneBase<T> poi risultano vuoti...
non devo usare un puntatore nella dichiarazione?
grazie dell'aiuto.
Prima di tutto: i nomi delle classi dovrebbero cominciare con una maiuscola. Non è obbligatorio, ma tutti scrivono così, quindi mi conformerei.

Hai definito un copy constructor e un operator=(const geneBase&) per la tua classe? Se sì, posta il codice, il problema è lì.
Perchè std::sort usa std::swap, che è definita così:
Codice:
template<class T> void swap(T& a, T& b)
{
    T temp = a; // Inizializzo temp copiando a, usando il costruttore geneBase(const geneBase&)
    a = b;        // Assegno b ad a con operator=(const geneBase&)
    b = temp;   // Assegno temp a b con operator=(const geneBase&)
}
Quindi, nell'inversione di posto di due elementi entra in gioco come gli oggetti della tua classe vengono copiati e/o copy-constructed. A seconda che il puntatore code sia usato come indirizzo o come array, dovrai comportarti diversamente. Ma con ogni probabilità devi gestirlo tu, perchè il copy constructor sintetizzato dal compilatore attualmente non fa quello che intendi tu.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 26-06-2013, 15:38   #3
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Ciao, grazie della risposta.


Si, allora intanto ho risolto evitando l'uso del puntatore.
ma dammi cmq un parere, ora l'operatore = è definito in questo modo:
Codice:
template <typename T>
geneBase<T>& geneBase<T>::operator=(const geneBase<T>& obj)
{
	if(&obj != this) 
	{
		// Copy elements
		this->code.clear();
		this->code = obj.code;
	}
	return *this;
}
sfrutto l'operatore = di vector che mi copia tutto l'array.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 26-06-2013, 16:17   #4
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Ciao, grazie della risposta.


Si, allora intanto ho risolto evitando l'uso del puntatore.
ma dammi cmq un parere, ora l'operatore = è definito in questo modo:
Codice:
template <typename T>
geneBase<T>& geneBase<T>::operator=(const geneBase<T>& obj)
{
	if(&obj != this) 
	{
		// Copy elements
		this->code.clear();
		this->code = obj.code;
	}
	return *this;
}
sfrutto l'operatore = di vector che mi copia tutto l'array.
Eviterei il clear, è ridondante: sia che il vettore da copiare è più grande o più piccolo, il vettore attuale viene distrutto. Se invece le dimensioni combaciano, gli elementi vengono copiati. Tra l'altro leggo ora qui che non è garantito che la memoria sia deallocata, quindi è inutile.

Cmq copiare interi vettori può essere pesante, cosa ci devi fare?

Ultima modifica di vendettaaaaa : 26-06-2013 alle 16:19.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 26-06-2013, 22:52   #5
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
sono algoritmi genetici... risolvono problemi di ottimizzazione combinatoria.
allora elimino il clear()!
In questo caso ordino l'array, si in effetti ci sono molti casi in cui devo copiare vettori, e poi ogni gene è una sequenza di valori quindi sostanzialmente il tutto è un vector di vector:
vector<vector<bool>> per esempio

quindi come dici, a questo punto meglio usare un puntatore dentro la classe, come avevo fatto all'inizio e modificare gli operatori vari... no?
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 27-06-2013, 16:39   #6
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
sono algoritmi genetici... risolvono problemi di ottimizzazione combinatoria.
allora elimino il clear()!
In questo caso ordino l'array, si in effetti ci sono molti casi in cui devo copiare vettori, e poi ogni gene è una sequenza di valori quindi sostanzialmente il tutto è un vector di vector:
vector<vector<bool>> per esempio

quindi come dici, a questo punto meglio usare un puntatore dentro la classe, come avevo fatto all'inizio e modificare gli operatori vari... no?
Se stai usando un compilatore che supporta C++11, definisci un move constructor per la tua classe:
Codice:
geneBase(geneBase&& other) : code(std::move(other.code)) { // Altro }
In questo modo, std::sort usa std::swap che nella versione C++11 sposta i vettori anzichè copiarli. Per ulteriori info, http://www.stroustrup.com/C++11FAQ.html#rval
Altrimenti bisogna metter mano ai puntatori e non è il massimo!

Ultima modifica di vendettaaaaa : 27-06-2013 alle 16:43.
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 27-06-2013, 16:52   #7
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
si C++ 11, grazie approfondisco.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 05-07-2013, 23:52   #8
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Ho applicato il tuo consiglio,
inoltre in tutte le altre operazioni di copa sto usando la nuova std::move().
La velocità è aumentata.

Una cosa che mi spiego ancora poco...
un programma in C# similare che avevo fatto in passato è molto ma molto più veloce... mi domando come può essere..

c'è una differenza sostanziale nel come vengono copiati gli array??
se non erro una list in C# è simile un stl vector in c++.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 06-07-2013, 00:51   #9
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Ho applicato il tuo consiglio,
inoltre in tutte le altre operazioni di copa sto usando la nuova std::move().
La velocità è aumentata.

Una cosa che mi spiego ancora poco...
un programma in C# similare che avevo fatto in passato è molto ma molto più veloce... mi domando come può essere..

c'è una differenza sostanziale nel come vengono copiati gli array??
se non erro una list in C# è simile un stl vector in c++.
Mah, posta il codice se puoi, son curioso! Anch'io in passato avevo fatto una specie di confronto tra C++ e C#...
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 06-07-2013, 12:33   #10
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Ho applicato il tuo consiglio,
inoltre in tutte le altre operazioni di copa sto usando la nuova std::move().
La velocità è aumentata.

Una cosa che mi spiego ancora poco...
un programma in C# similare che avevo fatto in passato è molto ma molto più veloce... mi domando come può essere..

c'è una differenza sostanziale nel come vengono copiati gli array??
se non erro una list in C# è simile un stl vector in c++.
Occhio che con C# difficilmente copi il contenuto (anzi copiare un oggetto in C# è proprio un incubo, alla fine sei costretto a serializzare e deserializzare un oggetto per clonarlo), più facile che tu abbia semplicemente copiato il riferimento.
Una condizione più simile al C# la ottieni usando gli smart pointer unique_ptr o shared_ptr.

Attenzione all'abuso della move semantic che è pensata per eliminare la doppia copia di oggetti temporanei e realizzare il perfect forwarding.
Spostare un oggetto lascia l'originale in uno stato consistente ma indefinito...
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 06-07-2013, 16:33   #11
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Gli array nella CLR funziona come gli array in C/C++ solamente se contengono value type (ricordo che String nonostante è classificato come value type, nella realtà è un referecence type)

http://www.codeproject.com/Articles/...R-Perspecti#20

In tutti gli altri casi, non è altro che un array di puntatori

Quote:
Attenzione all'abuso della move semantic che è pensata per eliminare la doppia copia di oggetti temporanei e realizzare il perfect forwarding.
Spostare un oggetto lascia l'originale in uno stato consistente ma indefinito...
No, è pensato anche per std::swap

Codice:
  /**
   *  @brief Swaps two values.
   *  @param  __a  A thing of arbitrary type.
   *  @param  __b  Another thing of arbitrary type.
   *  @return   Nothing.
  */
  template<typename _Tp>
    inline void
    swap(_Tp& __a, _Tp& __b)
#if __cplusplus >= 201103L
    noexcept(__and_<is_nothrow_move_constructible<_Tp>,
	            is_nothrow_move_assignable<_Tp>>::value)
#endif
    {
      // concept requirements
      __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)

      _Tp __tmp = _GLIBCXX_MOVE(__a);
      __a = _GLIBCXX_MOVE(__b);
      __b = _GLIBCXX_MOVE(__tmp);
    }
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11

Ultima modifica di nico159 : 06-07-2013 alle 16:35.
nico159 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2013, 13:56   #12
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da nico159 Guarda i messaggi
Gli array nella CLR funziona come gli array in C/C++ solamente se contengono value type (ricordo che String nonostante è classificato come value type, nella realtà è un referecence type)
String è un reference type immutabile non è un value type. In più gli operatori di uguaglianza comparano il contenuto piuttosto che il riferimento. Ma niente di string lo categorizza come value type.

Quote:
In tutti gli altri casi, non è altro che un array di puntatori
La differenza tra i 2 linguaggi si vede meglio paragonando List<T> a std::vector<T>, piuttosto che con gli array

Quote:
No, è pensato anche per std::swap

Codice:
  /**
   *  @brief Swaps two values.
   *  @param  __a  A thing of arbitrary type.
   *  @param  __b  Another thing of arbitrary type.
   *  @return   Nothing.
  */
  template<typename _Tp>
    inline void
    swap(_Tp& __a, _Tp& __b)
#if __cplusplus >= 201103L
    noexcept(__and_<is_nothrow_move_constructible<_Tp>,
	            is_nothrow_move_assignable<_Tp>>::value)
#endif
    {
      // concept requirements
      __glibcxx_function_requires(_SGIAssignableConcept<_Tp>)

      _Tp __tmp = _GLIBCXX_MOVE(__a);
      __a = _GLIBCXX_MOVE(__b);
      __b = _GLIBCXX_MOVE(__tmp);
    }
Infatti con la move semantic eviti le copie di oggetti anche durante lo swap
Lo swap è un caso applicativo in cui torna utile evitare le copie di troppo
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2013, 14:16   #13
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Quote:
String è un reference type immutabile non è un value type. In più gli operatori di uguaglianza comparano il contenuto piuttosto che il riferimento. Ma niente di string lo categorizza come value type.
Sì è così, non so perchè ero convinto che MS lo aveva inserito nella lista dei value type
Ho una pessima memoria
Quote:
La differenza tra i 2 linguaggi si vede meglio paragonando List<T> a std::vector<T>, piuttosto che con gli array
Non vedo il perchè, dato che entrambi lavorano sugli array - e quindi le differenze che si notano sono appunto conseguenza di cos'è un array per la CLR rispetto C/C++ e non come List internamente gestisce gli array

Quote:
Infatti con la move semantic eviti le copie di oggetti anche durante lo swap
Lo swap è un caso applicativo in cui torna utile evitare le copie di troppo
Risposta a:
Quote:
Attenzione all'abuso della move semantic
Quando è evidente che è la soluzione corretta per questo caso
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11

Ultima modifica di nico159 : 07-07-2013 alle 14:19.
nico159 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2013, 15:59   #14
tomminno
Senior Member
 
Iscritto dal: Oct 2005
Messaggi: 3306
Quote:
Originariamente inviato da nico159 Guarda i messaggi
Sì è così, non so perchè ero convinto che MS lo aveva inserito nella lista dei value type
Ho una pessima memoria

Non vedo il perchè, dato che entrambi lavorano sugli array - e quindi le differenze che si notano sono appunto conseguenza di cos'è un array per la CLR rispetto C/C++ e non come List internamente gestisce gli array
Semplicemente perchè std::vector è una classe
Quando in C# copi una lista o un array ne copi il riferimento, quando in C++ copi un vector esegui una deep copy, mentre con gli array essendo fondamentalmente dei puntatori questo non succede.

Quote:
Risposta a:

Quando è evidente che è la soluzione corretta per questo caso
Ovviamente l'abuso che se ne può fare è da parte del programmatore, gli algortimi della libreria standard come swap generalmente non soffrono di questi problemi
tomminno è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2013, 16:34   #15
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Quote:
Semplicemente perchè std::vector è una classe
Quando in C# copi una lista o un array ne copi il riferimento, quando in C++ copi un vector esegui una deep copy, mentre con gli array essendo fondamentalmente dei puntatori questo non succede.
Ah ecco, ora ti seguo maggiormente

Ma forse stiamo sbagliando entrambi

L'errore viene dal fatto che in C++ qualsiasi cosa può essere sia un value type o un reference type a seconda di come viene usato

geneBase contiene un vector - quindi hai ragione tu? No
geneBase contiene non un vector come di dici tu, ma un puntatore ad un vector

Quindi perchè non si comporta come in C#? Perchè forse è stato affrontato il problema dal punto di vista sbagliato, come con l'operatore = che non permette di sfruttare questa situazione

La soluzione migliore è quella di creare una specializzazione per std::swap che semplicemente scambi i due puntatori
Meno overhead rispetto a move, e si sfrutta il fatto che quel vector non è un "value type" ma un "reference type"
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11

Ultima modifica di nico159 : 07-07-2013 alle 16:41.
nico159 è offline   Rispondi citando il messaggio o parte di esso
Old 07-07-2013, 18:40   #16
vendettaaaaa
Senior Member
 
L'Avatar di vendettaaaaa
 
Iscritto dal: Jan 2012
Messaggi: 1267
Quote:
Originariamente inviato da nico159 Guarda i messaggi
La soluzione migliore è quella di creare una specializzazione per std::swap che semplicemente scambi i due puntatori
Meno overhead rispetto a move, e si sfrutta il fatto che quel vector non è un "value type" ma un "reference type"
Probabilmente è la soluzione più veloce, ma io eviterei il puntatore nudo e mi affiderei a std::move, sfuttando il move assignment del vector; dovrebbe esserci un overhead trascurabile. L'op che dice?
vendettaaaaa è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2013, 11:39   #17
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Data la differenza (notevole) di velocità, credo che il punto sia proprio che nel programma C++ CLR che ho scritto si fa una copia totale tutte le volte, quindi nel complesso rallenta molto.

Mentre in C# queste cose essendo già gestite il problema non mi è emerso...

Dovrei provare a lavorare con i puntatori, che di norma ok non si fa, ma in questo caso dove si lavora ad intensità di dati, ovvero alla fine è un continuo modificare array, sia lacosa migliore.

Ora ho anche un problemino di memoria, ovvero da qualche parte non sto rilasciando correttamente, dal debug noto che gli algoritmi di ordinamento fanno qualche pasticcio, prob. il mio operatore di copia non va bene.

Per quanto riguarda il confronto fra C++ e C# trovai un bell'articolo qui:
http://www.codeproject.com/Articles/...-Csharp-vs-NET
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2013, 11:44   #18
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Vi faccio vedere a pezzi, perchè il sorgente è un pò lungo...

Queste sono le due classi:
Codice:
#include "libsann.h"

namespace ga 
{
#pragma region Definitions
	template<typename T>
	class geneBase
	{
	public:
		geneBase(void);
		geneBase(uint len, double mrate = 0);
		geneBase(geneBase&& other);
		~geneBase(void);

		// set, get and edit code
		vector<T>* GetCode(void);
		void SetCode(vector<T> *_code);

		// Operators
		bool operator<(geneBase b)					{ return(fitness < b.GetFitness()); }
		geneBase& operator=(const geneBase& obj);

		geneBase& operator+(const geneBase& obj);
		geneBase& operator-(const geneBase& obj);
		geneBase& operator+=(const geneBase& obj);
		geneBase& operator-=(const geneBase& obj);

		geneBase<bool>& operator+(geneBase<bool>& obj);
		geneBase<bool>& operator-(geneBase<bool>& obj);
		geneBase<bool>& operator+=(geneBase<bool>& obj);
		geneBase<bool>& operator-=(geneBase<bool>& obj);
		
		// Mutation
		virtual void mutation(void);

		// Access methods
		inline double GetMutationRate(void)			{ return mate_rate; }
		inline void SetMutationRate(double value)	{ mutation_rate = value; }
		inline double GetFitness(void)				{ return fitness; }
		inline void SetFitness(double value)		{ fitness = value; }

		// Properties
		inline uint lenght(void)					{ return code.size(); }
		
		// Hamming distance
		static double HammingDistance(geneBase<T>& a, geneBase<T>& b);

		// Crossover
		static geneBase& crossover(
			geneBase<T>& a, geneBase<T>& b, crossover_mode m = crossover_mode::HAMMING, double mH = 0, uint pop_size = 0
			);

	protected:
		// The code of gene
		vector<T> code;
		// The fitness value
		double fitness;
		// Mutation rate
		double mutation_rate;
	};

	template <typename T>
	class populationBase
	{
	public:
		populationBase(double mrate = 0.05, double elitism_r = 0.1);
		populationBase(uint size, uint len, double mrate = 0.05, double elitism_r = 0.1);		// Auto-initialize population
		populationBase(vector<geneBase<T>> _pop, double mrate = 0.05, double elitism_r = 0.1);
		populationBase(populationBase&& obj);
		~populationBase(void);

		// Operators
		populationBase operator=(populationBase& obj);
		populationBase operator+(populationBase& obj);

		void join(const populationBase& obj);

		// Mate method
		void mate(crossover_mode mode = crossover_mode::HAMMING);
		// Genetic drift
		void BlockgeneticDrift(void);

		// Properties
		inline double GetDiversity(void) { return diversity; }
		inline double GetMaxHammingDistance(void) { return MaxHammingDistance; }
		inline uint Size(void) { return population.size(); }
		geneBase<T> BestGene(void);

		// Access methods
		vector<geneBase<T>> *PopulationPtr(void);

	protected:
		// Population
		vector<geneBase<T>> population;
		// Maximum Hamming distance
		double MaxHammingDistance;
		// Elitism rate
		double elitism_rate;
		// Default mutation rate
		double mutation_rate;

		uint RunRouletteWheel(utility::MyRandom random, double total_fit);
	};
#pragma endregion
Costruttori ed operatori, dove credo siano i problemi:

Codice:
#pragma region Gene implementation

#pragma region Constructors	/ Destructors
	template <typename T>
	geneBase<T>::geneBase(void)
	{
		fitness = 0;
		mutation_rate = 0;
	}

	template <typename T>
	geneBase<T>::geneBase(geneBase&& other)
	{
		code.assign(other.code.begin(), other.code.end());
		fitness = other.fitness;
		mutation_rate = other.mutation_rate;
	}

	geneBase<double>::geneBase(uint len, double mrate)
	{
		for(uint i = 0; i < len; i++)
		{
			code.push_back(((double)rand() / (double)RAND_MAX)); 
		}
		fitness = 0;
		mutation_rate = mrate;
	}

	geneBase<uint>::geneBase(uint len, double mrate)
	{
		for(uint i = 0; i < len; i++)
		{
			code.push_back((uint)rand()); 
		}
		fitness = 0;
		mutation_rate = mrate;
	}

	geneBase<bool>::geneBase(uint len, double mrate)
	{
		for(uint i = 0; i < len; i++)
		{
			code.push_back((rand() < (RAND_MAX/2)) ? true : false); 
		}
		fitness = 0;
		mutation_rate = mrate;
	}

	geneBase<char>::geneBase(uint len, double mrate)
	{
		for(uint i = 0; i < len; i++)
		{
			code.push_back((char)((rand() % 88)+32)); 
		}
		fitness = 0;
		mutation_rate = mrate;
	}

	template <typename T>
	geneBase<T>::~geneBase(void)
	{
		code.erase(code.begin(),code.end());
	}
#pragma endregion

#pragma region Operators
	template <typename T>
	geneBase<T>& geneBase<T>::operator=(const geneBase<T>& obj)
	{
		if(&obj != this) 
		{
			// Copy elements
			this->code.assign(obj.code.begin(),obj.code.end());
		}
		this->fitness = obj.fitness;
		this->mutation_rate = obj.mutation_rate;

		return *this;
	}

	template <typename T>
	geneBase<T>& geneBase<T>::operator+(const geneBase<T>& obj)
	{
		_ASSERT(code.size() == obj.GetCode().size());

		vector<T> *_code_ = new vector<T>();
		for(uint i = 0; i < code.size(); i++)
		{
			_code_->push_back(code.at(i) + obj.GetCode()->at(i));
		}

		geneBase<T> *C = new geneBase<T>();
		C->SetCode(_code);

		return *C;
	}

	template <typename T>
	geneBase<T>& geneBase<T>::operator-(const geneBase<T>& obj)
	{
		_ASSERT(code.size() == obj.GetCode().size());

		vector<T> *_code_ = new vector<T>();
		for(uint i = 0; i < code.size(); i++)
		{
			_code_.push_back(code.at(i) - obj.GetCode()->at(i));
		}

		geneBase<T> *C = new geneBase<T>();
		C->SetCode(_code);

		return *C;
	}

	template <typename T>
	geneBase<T>& geneBase<T>::operator+=(const geneBase<T>& obj)
	{
		_ASSERT(code.size() == obj.GetCode().size());

		for(uint i = 0; i < code.size(); i++)
		{
			code->at(i) += obj.GetCode()->at(i);
		}
		this->fitness = 0;
		return *this;
	}

	template <typename T>
	geneBase<T>& geneBase<T>::operator-=(const geneBase<T>& obj)
	{
		_ASSERT(code.size() == obj.GetCode().size());

		for(uint i = 0; i < code.size(); i++)
		{
			code.at(i) -= obj.GetCode()->at(i);
		}
		this->fitness = 0;
		return *this;
	}

	geneBase<bool>& geneBase<bool>::operator+(geneBase<bool>& obj)
	{
		_ASSERT(code.size() == obj.GetCode()->size());

		vector<bool> *_code_ = new vector<bool>();
		for(uint i = 0; i < code.size(); i++)
		{
			if(obj.GetCode()->at(i))
				_code_->push_back(true);
			else
				_code_->push_back(code.at(i));
		}

		geneBase<bool> *C = new geneBase<bool>();
		C->SetCode(_code_);

		return *C;
	}

	geneBase<bool>& geneBase<bool>::operator-(geneBase<bool>& obj)
	{
		_ASSERT(code.size() == obj.GetCode()->size());

		vector<bool> *_code_ = new vector<bool>();
		for(uint i = 0; i < code.size(); i++)
		{
			if(!(obj.GetCode()->at(i)))
				_code_->push_back(false);
			else
				_code_->push_back(code.at(i));
		}

		geneBase<bool> *C = new geneBase<bool>();
		C->SetCode(_code_);

		return *C;
	}

	geneBase<bool>& geneBase<bool>::operator+=(geneBase<bool>& obj)
	{
		_ASSERT(code.size() == obj.GetCode()->size());

		for(uint i = 0; i < code.size(); i++)
		{
			if(obj.GetCode()->at(i))
				code.at(i) = true;
		}
		this->fitness = 0;
		return *this;
	}

	geneBase<bool>& geneBase<bool>::operator-=(geneBase<bool>& obj)
	{
		_ASSERT(code.size() == obj.GetCode()->size());

		for(uint i = 0; i < code.size(); i++)
		{
			if(!(obj.GetCode()->at(i)))
				code.at(i) = false;
		}
		this->fitness = 0;
		return *this;
	}
#pragma endregion
secondo me in molti casi mi conviene lavorare con i puntatori, anche usando std::move come consigliato inizialmente, la velocità di C# rimane molto superiore, ma tuttavia, in c++ si dovrebber poter arrivare a prestazioni maggiori.

Non ho messo il codice inerente alla seconda classe, ma vale lo stesso discorso... dato che vi sono array di oggetti di tipo geneBase.

Io credo che l'operatore = sia uno dei problemi. credo mi convenga usare i puntatori, faccio un test e vi dico

Ultima modifica di Teo@Unix : 08-07-2013 alle 11:47.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2013, 12:54   #19
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Fossi in te:

Prima cosa:
geneBase<T>::geneBase(void)
Evita
geneBase<T>::geneBase()
E' corretto in C++

Costruttori semplici possono essere scritti come:
Codice:
geneBase() : fitness(0), mutation_rate(0) { }
Codice:
	template <typename T>
	geneBase<T>::geneBase(geneBase&& other)
	{
		code.assign(other.code.begin(), other.code.end());
		fitness = other.fitness;
		mutation_rate = other.mutation_rate;
	}
Così facendo, fai una copia di code (non si capisce cosa sia dal codice che hai passato, immagino un altro vector)

Quando usi swap, move e così via, devi "ricorsivamente" usare lo stesso costrutto sui membri "complessi" della classe

Codice:
	template <typename T>
	geneBase<T>::geneBase(geneBase&& other)
	{
		code = std::move(other.code);
		fitness = other.fitness;
		mutation_rate = other.mutation_rate;
	}
Codice:
	template <typename T>
	geneBase<T>::~geneBase(void)
	{
		code.erase(code.begin(),code.end());
	}
Assolutamente no
Non c'è bisogno di fare questo, la vita di code è collegata alla vita di geneBase, appena verrà distrutto geneBase verrà chiamato in automatico il distruttore di code, che a sua volta chiamerà i distruttori degli ogetti interni
Gli unici distruttori che vanno chiamati nel distruttore del loro container sono per i puntatori, ma con:
delete puntatore;

Codice:
	geneBase<bool>& geneBase<bool>::operator+=(geneBase<bool>& obj)
	{
		_ASSERT(code.size() == obj.GetCode()->size());

		for(uint i = 0; i < code.size(); i++)
		{
			if(obj.GetCode()->at(i))
				code.at(i) = true;
		}
		this->fitness = 0;
		return *this;
	}
vector di bool in C++ è una specializzazione, in realtà è un bitset
Non credo che potrai sfruttare a tuo favore questa caratteristica, ti conviene scegliere un'altra maniera per rappresentare i tuoi dati
Quello che stai facendo qua, è veramente lento

code ha lunghezza variabile durante il ciclo di vita dell'oggetto?
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11

Ultima modifica di nico159 : 08-07-2013 alle 16:49.
nico159 è offline   Rispondi citando il messaggio o parte di esso
Old 08-07-2013, 13:52   #20
nico159
Senior Member
 
Iscritto dal: Aug 2003
Città: Barletta (BA)
Messaggi: 939
Quote:
Originariamente inviato da Teo@Unix Guarda i messaggi
Data la differenza (notevole) di velocità, credo che il punto sia proprio che nel programma C++ CLR che ho scritto si fa una copia totale tutte le volte, quindi nel complesso rallenta molto.

Mentre in C# queste cose essendo già gestite il problema non mi è emerso...

Dovrei provare a lavorare con i puntatori, che di norma ok non si fa, ma in questo caso dove si lavora ad intensità di dati, ovvero alla fine è un continuo modificare array, sia lacosa migliore.

Ora ho anche un problemino di memoria, ovvero da qualche parte non sto rilasciando correttamente, dal debug noto che gli algoritmi di ordinamento fanno qualche pasticcio, prob. il mio operatore di copia non va bene.

Per quanto riguarda il confronto fra C++ e C# trovai un bell'articolo qui:
http://www.codeproject.com/Articles/...-Csharp-vs-NET
Dopo averti risposto al tuo ultimo reply, mi sento di dover rispondere qua:

Provengo anche io da C#, quindi credo che almeno in parte riusciremo a capirci a vicenda

Quote:
Mentre in C# queste cose essendo già gestite il problema non mi è emerso...
Questa è una falsa illusione, quello che C# fa per il programmatore è solo eliminare gli oggetti "inutilizzati" non fa altro
Il comportamento che vedi non è causa CLR, ma causa layout dei tuoi oggetti

Mi spiego, prima discutevo con tomminno perchè diceva "la differenza è..."
Ed ovviamente questo è il punto centrale del discorso

C#, Java ed i tanti linguaggi OOP con gc fanno dimenticare all'utente una cosa importantissima: capire come i propri dati sono rappresentati in ram

Cos'è in C# un oggetto?
Un contenitore di puntatori
Le uniche cose che contiene veramente, sono i value type

Immaginati ora il tuo List di geneBase in C#

Cos'è un array di geneBase in C#? Un Array di puntatori

Significa:
[pointer, pointer, pointer...]

Cos'è geneBase?
Un misto di value type ed altri puntatori
geneBase { fitness, mutation_rate, pointerTo_CodeList }

Cos'è code?
Un puntatore, che al suo interno ha
{ capacity, size, ...pointerTo_BoolArray }

Cos'è un Array di Bool?
[bool, bool...]

In C++ cos' è un array di geneBase?
[ { fitness, mutation_rate, { capacity, size, ..., pointerTo_Bitset }},
{ fitness, mutation_rate, { capacity, size, ..., pointerTo_Bitset }} ]

Quindi, alla fine, è anche meglio no?
No
Primo sta usando un bitset, quindi l'accesso ai singoli elmenti è LENTO
Secondo, non stai sfruttando il fatto che internamente vector conservi il puntatore ad un array - hai usato mode sulla tua classe, ma hai poi copiato i dati del bitset
Dovevi dare a tua volta move sul bitset - il bitset allora avrebbe sfruttato il fatto che internamente ha un puntatore ai dati

Ma scusa, C++ non è sempre meglio?
Non è il linguaggio a fare veloce un programma, ma gli algoritmi e il layout dei propri dati

C++ permette di scrivere codice migliore rispetto a C# perchè hai pieno controllo del layout dei tuoi dati

Quando si scrive un sw ad alte performance, il layout dei dati è una cosa fondamentale da considerare

Oggi il collo di bottiglia di ogni software, è l'accesso ai dati
Se vuoi un software performance, devi prima di tutto pensare al design delle tue strutture dati e come sono rappresentate in memoria

MS al Build 2013 ha dedicato un talk al riguardo:
Native Code Performance and Memory: The Elephant in the CPU
http://channel9.msdn.com/Events/Build/2013/4-329

Nessun linguaggio può fare per te queste scelte, nessun compilatore
Sei tu che sei chiamato a farlo
C# ti impone una visione basata sui puntatori, che distrugge il data locality e quindi ogni speranza di avere buone performance

E' una illusione pensare che C# faccia scelte per te. Ti impone solo una strada che genericamente dovrebbe andar bene per la maggior parte dei casi

Se vuoi performance simili, devi usare solamente struct in C# che sono limitate e scomode da usare

Ecco perchè, discutevo con tomminno sul fatto che il problema parte da altro - e credo che alla fine entrambi dicevamo la stessa cosa

Altra cosa importante, i puntatori non sono il male
Se l'oggetto che usa il puntatore segue la regola dei tre http://en.wikipedia.org/wiki/Rule_of...programming%29 non c'è possibilità di trovarsi in problemi
Il problema si ha quando i puntatori non hanno un ciclo di vita chiaro al programmatore
Ovvero il programmatore non sa, come il proprio algoritmo dovrà funzionare (incapacità? Troppa complessità?) e quindi si eliminano puntatori prima, si accedono a puntatori ormai eliminati, non si eliminano proprio, e così via

Come vedi, la riflessione non è su C# vs C++
Ma più che altro un problema di programmazione pura:
Gestione delle proprie strutture dati, layout dei dati, pattern di accesso ai dati, algoritmi
__________________
In a world without fences, who needs Gates?
Power by: Fedora 8 - Mac OS X 10.4.11

Ultima modifica di nico159 : 08-07-2013 alle 16:56.
nico159 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Motorola edge 70: lo smartphone ultrasottile che non rinuncia a batteria e concretezza Motorola edge 70: lo smartphone ultrasottile che...
Display, mini PC, periferiche e networking: le novità ASUS al CES 2026 Display, mini PC, periferiche e networking: le n...
Le novità ASUS per il 2026 nel settore dei PC desktop Le novità ASUS per il 2026 nel settore de...
Le novità MSI del 2026 per i videogiocatori Le novità MSI del 2026 per i videogiocato...
I nuovi schermi QD-OLED di quinta generazione di MSI, per i gamers I nuovi schermi QD-OLED di quinta generazione di...
POCO M8: display AMOLED luminoso, batter...
ECOVACS, tante novità a Las Vegas...
Caso Galaxy Ring difettoso: Samsung chiu...
Targa e assicurazione per monopattini el...
AI Cloud Protect: la soluzione di Check ...
Nuovo spettacolare video del razzo spazi...
Hisense presenta a CES 2026 il display M...
XPeng P7+ è pronta per l'Europa: ...
IKEA nuove lampade Matter annunciate al ...
Il telescopio Hubble potrebbe andare dis...
Hisense introduce RGB MiniLED evo (a qua...
Deumidificatore De'Longhi in offerta su ...
OnePlus 15R: il 'battery phone' pi&ugrav...
Beats Studio Pro a un super prezzo su Am...
Car of the Year, la Mercedes CLA eletta ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:05.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v