Copy Constructor langsam?



  • Hallo 🙂

    für einen Algorithmus initialisiere ich ein paar klassen, die viele Dinge vorab berechnen und speichern. (Lookup Tables, Strukturen, etc).
    Für Multithreading möchte ich für jede Instanz eines Threads diese Klassen kopieren. dafür Copy Constructor.

    Jetzt zeigt sich das ganze allerdings als ziemlich Langsam.
    Das erstellen und vorabberechnen dauert etwa 3 Sekunden.
    Der Copy Constructor benötigt 39 Sekunden??

    Und ich weiß nicht mal genau woran es denn liegt, da es außerhalb meines Codes zur wartezeit kommt.
    Hier die Beiden Constructor mit Markierung wo genau die 39 Sekunden Verstreichen:

    _DBHistogramScan::_DBHistogramScan(_DBHistogramScan& other) {
    	m_DimOfData						= other.m_DimOfData;
    	m_absDataRange					= other.m_absDataRange;
    	m_dataAmount_UpperAssignment	= other.m_dataAmount_UpperAssignment;
    	m_epsDBScan						= other.m_epsDBScan;
    	m_minPointsDBScan				= other.m_minPointsDBScan;
    	m_rMinScanRange					= other.m_rMinScanRange;
    	m_rMaxScanRange					= other.m_rMaxScanRange;
    	m_DataIsSet						= other.m_DataIsSet;
    
    	// Bis hier keine Verzögerung - Zeit ~ 0
    	m_Histogram						= _Histogram(other.m_Histogram); 
    	// Hier Zeit ~ 39 Sekunden
    	cout << "#"; 
    	m_DBScan						= _DBScan(other.m_DBScan);
    	cout << "#";
    
    	m_pFilteredDataVector3D			= other.m_pFilteredDataVector3D;
    	m_pFilteredDataVector2D			= other.m_pFilteredDataVector2D;
    
    }
    
    _Histogram::_Histogram(_Histogram& other) {
    
    	m_Dimension					= other.m_Dimension;
    	m_BinWidth					= other.m_BinWidth;
    	m_BinScaleFactor			= other.m_BinScaleFactor;
    	m_DataRange					= other.m_DataRange;
    	m_BinOffset					= other.m_BinOffset;
    	m_uNumBins1Dim				= other.m_uNumBins1Dim;
    	m_uNumBins2Dim				= other.m_uNumBins2Dim;
    
    	m_Bins						= other.m_Bins;
    
    	m_BinOrder					= other.m_BinOrder;
    
    	m_BinIDCenterDistSquare		= other.m_BinIDCenterDistSquare;
    
    	cout << "*"; // Bis hier hin Ohne verzögerung.  Zeit ~ 0
    
    }
    

    Kann mir jemand sagen was außerhalb meines Codes (Beim ende des Copy Constructor) so lange benötigt? Oder/Und wie ich das ganze schneller Koppieren kann? Die Klassen speichern ihre LookupTables alle in 1D Std::vectoren



  • Du benutzt an der Stelle nicht den Copy-C'tor von Histogramm.

    Zeig mal Standard-C'tor und Zuweisung von histogramm .
    Denn das passiert: m_histogramm wird mit dem Standard-C'tor erstellt und danach wird eine Zuweisung durchgeführt.

    Warum das so ist?
    Weil Du keine Member initializer list verwendest.



  • Also erst mal ist das kein Copy Constructor, da der "other" nicht const ist. Dann würde ich Dir die Verwendung von Initialisierungslisten nahelegen. Also so:

    _DBHistogramScan::_DBHistogramScan(const _DBHistogramScan& other)
      : m_DimOfData(other.m_DimOfData),
        m_absDataRange(other.m_absDataRange),
        m_dataAmount_UpperAssignment(other.m_dataAmount_UpperAssignment),
        m_epsDBScan(other.m_epsDBScan),
        m_minPointsDBScan(other.m_minPointsDBScan),
        m_rMinScanRange(other.m_rMinScanRange),
        m_rMaxScanRange(other.m_rMaxScanRange),
        m_DataIsSet(other.m_DataIsSet),
        m_Histogram(other.m_Histogram),
        m_DBScan(other.m_DBScan),
        m_pFilteredDataVector3D(other.m_pFilteredDataVector3D),
        m_pFilteredDataVector2D(other.m_pFilteredDataVector2D)
    {
    }
    

    Bei _Histogram genauso.

    Das löst allerdings nicht das Problem. Aber Du hast ja bereits herausgefunden, dass die Verzögerung im Konstruktor von _DBScan statt findet. Den Konstruktor solltest Du Dir mal genauer anschauen.



  • Danke 🙂

    Ich bin gerade selbst dahinter gekommen das nach dem ende vom Copy Const. ein Return steht. Es wird ja eine Klasse zurückgegeben. Und das, was auch immer da genau passiert dauert ewig.

    Ich habe jetzt folgendes gemacht:

    void					_Histogram::operator = (const _Histogram& other) {
    	m_Dimension					= other.m_Dimension;
    	m_BinWidth					= other.m_BinWidth;
    	m_BinScaleFactor			= other.m_BinScaleFactor;
    	m_DataRange					= other.m_DataRange;
    	m_BinOffset					= other.m_BinOffset;
    	m_uNumBins1Dim				= other.m_uNumBins1Dim;
    	m_uNumBins2Dim				= other.m_uNumBins2Dim;
    
    	m_Bins						= other.m_Bins;
    
    	m_BinOrder					= other.m_BinOrder;
    
    	m_BinIDCenterDistSquare		= other.m_BinIDCenterDistSquare;
    
    }
    

    Natürlich für alle Klassen, nach dem selben Schema. Jetzt dauert das Copy aller Klassen nur noch wenige Millisekunden.
    = Funktionalität einwandfrei.
    Ist es vom Stil her auch ok?



  • cl90 schrieb:

    Ist es vom Stil her auch ok?

    Wahrscheinlich ist es unnötig. Nimm es mal raus und schau, ob es noch kompiliert.

    Wenn ja, dann wird ein copy-assignment-operator vom Compiler generiert und der macht genau das gleiche.



  • Der Assignment-Operator sieht aus, als würde er einfach alle Member kopieren. Definierst Du ihn nicht, wird der Compiler dir genau den implizit zur Verfügung stellen. Also brauchst Du ihn nicht.

    Ausserdem sollte er eine Referenz auf *this zurück liefern. Ist nicht unbedingt nötig aber doch sehr üblich.


  • Mod

    tntnet schrieb:

    Also erst mal ist das kein Copy Constructor, da der "other" nicht const ist.

    Das const ist für die Klassifizierung als copy-ctor unerheblich.

    struct foo
    {
        foo(foo&);
        foo(const foo&);
        foo(volatile foo&);
        foo(const volatile foo&);
    };
    

    Alle aufgeführten Formen sind copy-ctors.

    Es sieht ja ohnehin so aus, als ob im vorliegenden Fall, ein default copy-ctor und copy-assignment-op ausreichend sind. Ohne die Klassendefinition zu kennen, kann man das nat. nicht mit absoluter Sicherheit sagen.


Anmelden zum Antworten