Sort mit Zeigern



  • Hallo,

    ich stehe gerade vor einer kleinen Herausforderung, mit dem Ziel mein Programm so schnell wie
    möglich zu machen.

    Im Moment erhalte ich von mehreren Threads Daten, die ich in einem Thread speichere
    und sortiere

    In etwa so:

    void ObjectCollected::CollectDATA(std::vector<std::vector<unsigned int>>  dataTCP)
    {
    	for(...)
    	{
    	std::vector<unsigned int>ALL_small;
    
    	ALL_small.push_back(dataTCP[dat][0]);
    	ALL_small.push_back(dataTCP[dat][1]);
    	...
    	Big_DATA.push_back(ALL_small);
    	small.clear();
    	}
    ...
    }
    

    und mit

    std::sort(Big_DATA.begin(), Big_DATA.end(), [](const std::vector<unsigned int>& a,const std::vector<unsigned int>& b){return a[0] < b[0]; });

    sortiere ich die Daten nach der ersten variable für die weitere Verarbeitung.

    ......
    Nun, die eigentlich Frage. Wie kann ich mehrere Zeiger zu einem verbinden und als input für sort benutzen.

    Den speicherplatz von dataTCP_Pointer habe ich durch dataTCP.resize schon im vorfeld
    reserviert.

    also in etwa so:

    void ObjectCollected::CollectDATA(std::vector<std::vector<unsigned int>>  *dataTCP_Pointer)
    {
    	std::vector<std::vector<unsigned int>> *dataTCP[10];
    	if(daten von 0) dataTCP[0]= dataTCP_Pointer;
    	if(daten von 1) dataTCP[1]= dataTCP_Pointer;
    
    	// sort
    
    }
    

    Ps.: über einen Beispiel code würde ich mich sehr freuen. 😃

    Grüße



  • Wenn ich den Problem richtig verstanden habe, dann möchtest du deinen Vector von Vectoren sortieren, aber möglichst ohne Kopie zu erstellen? Dazu muss man nicht auf Pointer zurückgreifen sondern kann überall Referenzen nutzen:

    void ObjectCollected::CollectDATA(const std::vector<std::vector<unsigned int>>& dataTCP)
    {
      typedef std::reference_wrapper<const std::vector<unsigned int>> VecRef;
      std::vector<VecRef> Big_DATA(dataTCP.begin(), dataTCP.end());
      std::sort(Big_DATA.begin(), Big_DATA.end(), [](const std::vector<unsigned int>& a, const std::vector<unsigned int>& b) {return a[0] < b[0]; });
    
    }
    

    Ein Trick hier ist die Verwendung von std::reference_wrapper weil man nicht direkt einen Vector von References erstellen kann.



  • Der Vollständigkeit halber hier noch die Version mit Pointern:

    void CollectDATA(const std::vector<std::vector<unsigned int>>& dataTCP)
    {
      std::vector<const std::vector<unsigned int>*> Big_DATA(dataTCP.size());
      std::transform(dataTCP.begin(), dataTCP.end(), Big_DATA.begin(), [](const std::vector<unsigned int>& v){ return &v; });
      std::sort(Big_DATA.begin(), Big_DATA.end(), [](const std::vector<unsigned int>* a, const std::vector<unsigned int>* b) {return (*a)[0] < (*b)[0]; });
    
    }
    

    Wenn man allerdings schon Pointer benutzt dann bitte nur da wo es nötig ist. Der Parameter braucht kein Pointer zu sein und du brauchst auch keine Pointer auf Vektoren von Vektoren sondern einen Vektor von Pointern auf Vektoren.



  • Hi, danke für die Antwort 👍

    Heißt es dann wenn ich die Klasse so definiere:

    typedef std::reference_wrapper<const std::vector<unsigned int&gt;&gt; VecRef;
    std::vector<VecRef&gt; CollectDATA_BIG;
    

    und bei jedem Funktionsaufruf

    void ObjectCollected::CollectDATA(std::vector<std::vector<unsigned int&gt;&gt; *dataTCP)
    {
    ...
     for(n)
     {
     CollectDATA_BIG.push_back(dataTCP[n][0]);
     }
    }
    

    aufrufe.

    Dann würde die VecRef CollectDATA_BIG auf alle ankommenden vecotren verweisen, ohne eine kopie zu erstellen ?

    So das ich nur noch CollectDATA_BIG sortieren muss.
    Richtig ?



  • Dein CollectDATA_BIG ist eine Membervariable bzw. global? Kann man machen allerdings muss man dann aufpassen, dass die ursprünglichen Vektoren nicht zerstört werden, sonst hat man Referenzen auf gelöschte Sachen.

    Warum hat deine Funktion jetzt schon wieder Pointer für den Parameter? Hast du wirklich ein Array von Vektoren von Vektoren? Pointer auf Arrays sind böse.



  • @sebi707

    vielen Dank, du hast mir sehr geholfen 👍 👍 👍 👍



  • Eine Frage zu dem Thema hätte ich noch:

    Im Moment ist es so, dass ich von mehreren threads Zeiger auf zweidimensionale Vektoren erhalte.

    Dank deiner Hilfe habe ich eine Referenz die auf diese Zeiger verweist und nach dem ersten Parameter sortiert.
    Im weiteren Verlauf gehe ich mit einer Schleife die ersten Parameter durch und kopiere die Vektoren die denselben ersten Parameter haben in eine Zeile, wobei die Zeilenposition durch einen anderen Parameter definiert ist.

    Um es besser zu verstehen hier ein Beispiel:

    Vec1[10][13], Vec2[10][13].... auf beide verweist nun Vec3 -> dieser wird nach dem ersten der 13 Parameter sortiert.

    Dadurch haben wir so etwas wie
    Vec3:

    11 0 0 0 0 0 …
    11 0 0 0 0 2 …
    11 0 0 0 0 1 …
    12 0 0 0 0 0…

    Und nun wird Vec4 reserviert und abhängig von vom Parameter 6 sortiert, so dass am Ende Vec4 so ausschaut.

    Vec4:
    11 0 0 0 0 0 … 11 0 0 0 0 1 … 11 0 0 0 0 2… 12 0 0 0 0 0 …

    Das funktioniert soweit. Aber ich würde das ganze gerne beschleunigen. Also so wenig wie möglich kopieren.
    (Bis am Ende alles sortiert ist und ich neue Daten habe)

    Ich habe es so wie du mit dem reference_wrapper probiert also einen neuen Vec4 erstellt aber es stand in jeder Zeile dasselbe.


Log in to reply