Iteration Performance abhängig von Objektgröße?



  • Ich meine den Speicher, den Dein Programm allokiert, wenn Du die Liste gefüllt hast.
    Wie wäre es mal mit Code?

    Außerdem sagst Du, Deine Liste hält nur Pointer. Die sind eh immer gleich groß, egal wie groß Deine X-Objekte selbst sind. Irgendwas ist da mal wieder komisch, bei Dir.
    Und ist wirklich auch das iterieren langsamer? Oder nur das Einfügen/Löschen?



  • Poste mal ein Codebeispiel mit dem man das nachvollziehen kann.



  • dazu müsste ich zuviel code posten... ich mach mal ne testumgebung.. und testes es ohne das drumherum.. wenns dann immer noch so ist, dann poste ich den code:)



  • #include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    #include <vector>
    #include <list>
    
    class Foo{
    public:
    	double dDATA[40];
    
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	std::vector<Foo> vDat(10000);
    
    	std::list<Foo*> lDat;
    
    	for(int i=0; i< 10000; i++)
    		lDat.push_back(&vDat[i]);
    
    	long lStart= timeGetTime();
    
    	for(int k=0; k< 100; k++){
    
    		for(std::list<Foo*>::iterator it = lDat.begin(); it != lDat.end(); it++)
    			double d= (*it)->dDATA[0];
    
    	}
    	std::cout << "Time: " << (timeGetTime()-lStart) << std::endl;
    	return 0;
    }
    

    so jung, verändert mal die größe von dDATA[40] 😉

    dDATA[8] = 748ms
    dDATAT[16]= 865ms

    sind immerhin 110ms .. das kann ja nich an der zeitmessung toleranz liegen



  • Ja, in so einem Fall ist es besser/schneller Pointer auf die Objekte in der Liste zu speichern.



  • ja das mach ich ja, trozdem variert die iterationgeschwindigkeit;)



  • Also im Releasemode hab ich da immer 0ms.
    Wenn ich es mit 10000 Durchgängen mache

    for(int k=0; k< 10000; k++){
    
            for(std::list<Foo*>::iterator it = lDat.begin(); it != lDat.end(); it++)
                double d= (*it)->dDATA[0];
    
        }
    

    dann hab ich
    8: Time: 640
    16: Time: 640
    16000: Time: 641

    Mach mal mehr Durchgänge, dann wird der prozentuale Unterschied nicht mehr so groß sein.

    dust schrieb:

    Ja, in so einem Fall ist es besser/schneller Pointer auf die Objekte in der Liste zu speichern.

    Beim iterieren? Wie kommst du darauf?



  • Also ich kann im Releasemodus vom VC++ 2005 keine Unterschiede messen, selbst wenn ich die Anzahl der Iterationen verhundertfache (sonst kommen zwischen 0 und 15 ms raus).



  • Jup, bei mir auch. 0ms im Release Build.



  • also ich habs ma ein klein wenig abgeändert...

    #include <iostream> 
    #include <vector> 
    #include <list> 
    #include <ctime>
    
    #define DOUBLE_ARRAY_LENGHT 100
    #define ARRAY_MAX 10000
    #define COUNT_MAX 100
    
    /* "Messwerte", 32bit vista, vs 2005 team suite, release mode
    40, 10000, 100:
    	32
    	25
    	27
    	27
    	18
    	23
    	20
    	21
    	=> 193 / 8
    100, 10000, 100:
    	17
    	30
    	52
    	21
    	16
    	20
    	19
    	20
    	=> 195 / 8
    */
    
    struct Foo
    	{ 
    		double dDATA[DOUBLE_ARRAY_LENGHT]; 
    	}; 
    
    int main (int argc, char* argv[]) 
    { 
        std::vector<Foo> vDat (ARRAY_MAX); 
        std::list<Foo*> lDat;
    
        for(size_t i=0; i != ARRAY_MAX; i++) 
            lDat.push_back(&vDat[i]); 
    
    	clock_t first = 0;
    	clock_t second = 0;
        for(size_t k (0); k != COUNT_MAX; ++k)
    		{
    			const std::list<Foo*>::iterator end (lDat.end());
    			for(std::list<Foo*>::iterator it = lDat.begin(); it != end; ++it)
    				{
    					first += clock();
    					double d= (*it)->dDATA[0]; 
    					second += clock();
    				}
    	    }
        std::cout << "Clock: " << static_cast <double> (second - first) << std::endl; 
    	return 0; 
    }
    

    bb 😛

    PS: auch bei DOUBLE_ARRAY_LENGTH == 1000 werden die Werte bei mir nicht größer - habs zwar au nicht aufgerechnet oder so, aber die Zahlen bewegten sich wieder in dem Bereich

    EDIT:
    sry, so wie oben is das bissl doof ^^

    Habs so gemacht: Ergebnis:

    clock_t second = 0;
    	clock_t first = clock ();
        for(size_t k (0); k != COUNT_MAX; ++k)
    		{
    			const std::list<Foo*>::iterator end (lDat.end());
    			for(std::list<Foo*>::iterator it = lDat.begin(); it != end; ++it)
    				{
    					double d = (*it)->dDATA[0]; 
    				}
    	    }
    	second = clock ();
    

    Hab DOUBLE_ARRAY_LENGHT == 1 und == 10000 gewählt - beide Male kam immer 3 raus.

    bb



  • naja wenn data 150 groß ist, oder nur 16 variert es um 80ms... release.. VC++ 2003



  • clock_t first = 0;
        clock_t second = 0;
        for(size_t k (0); k != COUNT_MAX; ++k)
            {
                const std::list<Foo*>::iterator end (lDat.end());
                for(std::list<Foo*>::iterator it = lDat.begin(); it != end; ++it)
                    {
                        first += clock();
                        double d= (*it)->dDATA[0];
                        second += clock();
                    }
            }
        std::cout << "Clock: " << static_cast <double> (second - first) << std::endl;
    

    solltest du clock frist nich über die schleif setzen, und second drunter?



  • Joar, sry - ist mir vorhin (nat. erst als ich meinen Post noch ma durchgelesen hatte) auch aufgefallen xD



  • BorisDieKlinge schrieb:

    naja wenn data 150 groß ist, oder nur 16 variert es um 80ms... release.. VC++ 2003

    Ich habe null Unterschied, selbst, wenn data mal 10 und mal 5000 groß ist.



  • hmm komsich 😉 da muss ich wohl mal bischen tiefer rein schaun;)


  • Mod

    double d= (*it)->dDATA[0];
    

    Sinnlos, kann unmittelbar wegoptimiert werden, da d nicht weiter benutzt wird. Wird es nicht wegoptimiert (z.B. wegen)

    d+= (*it)->dDATA[0];
    

    (und irgendwo am Ende ausgeben) - wird man dagegen eine Abhängigkeit der Größe von dData und dem vector feststellen, einfach wegen begrenzter Speicherbandbreite.



  • verdammt - da haste nat. recht xD

    double d (0);
        for(size_t k (0); k != COUNT_MAX; ++k)
    		{
    			const std::list<Foo*>::iterator end (lDat.end());
    			for(std::list<Foo*>::iterator it = lDat.begin(); it != end; ++it)
    				{
    					d += (*it)->dDATA[0]; 
    				}
    	    }
    	std::cout << d << std::endl; //oder iwas anders mit d machen
    

    =>

    #define ARRAY_MAX 10000
    #define COUNT_MAX 100
    
    #define DOUBLE_ARRAY_LENGHT 1
    => 3
    #define DOUBLE_ARRAY_LENGHT 10000
    => 9
    

    bb



  • hmm jetzt müsste man mal testen wie sie die performanteverhälte beim einfügen und löschen von foo pointern in der liste



  • hf : P



  • Soo hier hab ich ne modifizierte Version. ich füge Foo Pointer in eine Liste hinzu, (kopiere von lDat nach lDatDest, und lösche lDatDest wieder..

    Size 1 Time: 2094
    Size 2 Time: 1127
    Size 4 Time: 2134
    Size 8 Time: 938
    Size 16 Time: 1513
    Size 32 Time: 2383
    Size 64 Time: 2248
    Size 128 Time: 2455
    Size 256 Time: 2474
    Size 512 Time: 2462
    Size 1024 Time: 2459
    Size 2048 Time: 2498
    Size 4096 Time: 761
    Size 8192 Time: 1303
    Size 16384 Time: 599
    Size 32768 Time: 1223
    Size 65536 Time: 312
    
    class Foo{
    public:
    	double dDATA[1];
    
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	std::vector<Foo> vDat(1000);
    
    	std::list<Foo*> lDat;
    
    	std::list<Foo*> lDatDest;
    
    	for(int i=0; i< 1000; i++)
    		lDat.push_back(&vDat[i]);
    
    	long lStart= timeGetTime();
    
    	for(int k=0; k< 100; k++){
    
    		//lDat Foo Pointer in lDatDest kopieren
    		for(std::list<Foo*>::iterator it = lDat.begin(); it != lDat.end(); it++)
    			lDatDest.insert(lDatDest.begin(), (*it));
    
    		//Und wieder löschen
    		while(lDatDest.size())
    			lDatDest.erase(lDatDest.begin());
    
    	}
    	std::cout << "Time: " << (timeGetTime()-lStart) << std::endl;
    	return 0;
    }
    

    was ist da los? ich kopiere doch nur POINTER nicht die objekte...


Anmelden zum Antworten