string kopiert oder nicht?



  • Moin,

    void fooCopy(string s)
    {
    //...
    }
    void fooConst(const string s)
    {
    //...
    }
    void fooRef(const string& s)
    {
    //...
    }
    

    Annahme:
    Der String braucht in der Funktion nicht verändert werden.

    Frage:
    Wird von der STL in der Funktionen fooCopy/fooConst eine echte Kopie von s angelegt? Oder ist
    die STL so schlau/optimiert das erst bei Zugriff auf Änderungen eine Kopie angelegt wird?

    Wie könnte man das heraus bekommen, nachweisen?



  • Du willst auf Copy-On-Write hinaus? Ohne die Sourcen zu sehen, könnte man das einfach durch Geschwindigkeitsmessung herausfinden. Allerdings ist Copy-On-Write meines Wissens etwas in Verruf gekommen, weil es da mit der Threadsicherheit nicht so rosig aussieht ... such mal in comp.lang.c++.moderated nach "cow".

    [ Das alles setzt natürlich vorraus, dass basic_string ohne Compilermagie implementiert ist. ]



  • Genau Copy-On-Write.

    Es geht mir nicht um Magic-Einstellung des Compilers, sondern Plain-Standard so wie es vor gesehen ist.
    Ich würde erwarten das eine Kopie angelegt, bei fooCopy.
    Bei fooConst bin mich nicht so sicher. Mein Problem ist in der Tat die Threadssicherheit. Ich habe bis jetzt keine schlecht Erfahrung gemacht, aber ich entwickel unter gcc und vc. Nun ist die STL-Implementierung nicht identisch und Copy on Write ist doch recht verführerisch, oder? Ich möchte nämlich kein Copy on Write haben.

    Eine Zeitmessung!? Ich hatte sowas befürchtet.

    comp.lang.c++.moderated ??
    Werde nicht wirklich schlau wo das sein soll.
    Könntest du mir den Link vollständig geben 🙂



  • Vom Standard her ist es weder vorgeschrieben noch verboten COW-String zu bauen.
    Das darf sich jeder Bilbiothekschreiber selber aussuchen.

    Und ich denke, daß wenn im ersten Fall eine vollständige Kopie erzeugt wird, dann auch im zweiten.



  • idefix schrieb:

    comp.lang.c++.moderated ??
    Werde nicht wirklich schlau wo das sein soll.
    Könntest du mir den Link vollständig geben 🙂

    Der Link ist vollständig. 🙂
    Du brauchst aber einen News-Reader zum Anzeigen. Zur Not tuts auch Outlook Express.



  • comp.lang.c++.moderated ??
    Werde nicht wirklich schlau wo das sein soll.

    Das findest du im Usenet. Wenn due keinen reader hast versuchs mal über googel. Unter "groops" kannst du dir ein paar der usegroups ansehen. Die besagte Gruppe ist dabei.

    BTW: In singelthreaded Anwendungen ist COW immernoch von Vorteil.

    Es gibt auch ein GotW zu diesem Thema. Ich glaub es hieß Optimisations that aren't oder so.



  • Danke für die Hinweise in den Groups. Von alleine wäre ich nicht darauf
    gekommen. Jetzt muß ich es erst einmal lesen.

    Allerdings, hatte ich mich doch schon tatsächlich hingesetzt und die Zeit gemessen. 🕶

    Nun, gut. Dabei ist für mich heraus gekommen, das const string&
    ca. 1/10 schneller ist und bei string kopiert wird und bei const string& nicht.
    Wenn ich das mal so pauschalieren darf.

    Allerdings habe ich eine kleine Merkwürdigkeit festgestellt. Da ich von
    Haus aus nicht fleißig bin habe ich mit Templates angefangen. Das Template Funktionen
    nicht unbeding das machen was man erwartet ist nichts neues (beruht wohl auf Gegenseitigkeit).
    Also mußte ich die Templates ein wenig austricksen (naja, vieleicht eher mich).
    Ursprünglich hatte ich es so wie die Fkt strange, hatte aber kein Unterscheid in der Zeit
    feststellen können.

    Gibt es hier für irgendeine Erklärung?

    #include <stdlib.h>
    #include <time.h>
    
    #include <string>
    #include <iostream>
    
    using std::string;
    
    const unsigned short nREC	= 500;
    const unsigned short nLOOP	= 3000;
    const unsigned short nLEN	= 1024;
    
    ///////////////////////////////////////////////////////////
    template<class T> void str(unsigned short i,T s)
    {
    	if(i<nREC)
    	{ 
    		str<T>(++i,s);
    	}
    }
    ////
    template<class T> void loop(T sCase)
    {
    	clock_t	start= clock();
    
    	for(unsigned short j=0;j<nLOOP;j++)
    	{
    		string s(nLEN,char(j%('z'-'a')+'a'));
    
    		str<T>(0,s);
    	}
    	std::cout<<"loop "<<sCase<<" "<<clock()-start<<std::endl;
    }
    ///////////////////////////////////////////////////////////////
    template<class T> void strange(const string& sCase)
    {
    	clock_t	start= clock();
    
    	for(unsigned short j=0;j<nLOOP;j++)
    	{
    		string s(nLEN,char(j%('z'-'a')+'a'));
    
    		str<T>(0,s);
    	}
    
    	std::cout<<"strange "<<sCase<<" "<<clock()-start<<std::endl;
    }
    ///////////////////////////////////////////////////////////////
    void strRef(unsigned short i, const string& s)
    {
    	if(i<nREC)
    	{
    		strRef(++i,s);
    	}
    }
    ////
    void loopRef()
    {
    	clock_t	start= clock();
    
    	for(unsigned short j=0;j<nLOOP;j++)
    	{
    		string s(nLEN,char(j%('z'-'a')+'a'));
    
    		strRef(0,s);
    	}
    
    	std::cout<<"loop Ref "<<clock()-start<<std::endl;
    }
    ///////////////////////////////////////////////////////////
    void strCopy(unsigned short i,string s)
    {
    	if(i<nREC)
    	{
    		strCopy(++i,s);
    	}
    }
    ////
    void loopCopy()
    {
    	clock_t	start = clock();
    
    	for(unsigned short j=0;j<nLOOP;j++)
    	{
    		string s(nLEN,char(j%('z'-'a')+'a'));
    
    		strCopy(0,s);
    	}
    
    	std::cout<<"loop Cpy "<<clock()-start<<std::endl;
    }
    ///////////////////////////////////////////////////////////
    int main(int argc, char* argv[])
    {
    	loopCopy();
    	loopRef();
    
    	loop<const string&>("ref");
    	loop<string>("cpy");
    
    	strange<const string&>("ref");
    	strange<string>("cpy");
    
    	getchar();
    
    	return 0;
    }
    


  • Helium schrieb:

    BTW: In singelthreaded Anwendungen ist COW immernoch von Vorteil.

    Also in More Exceptional C++ ist hinten ein Benchmark drin. Ambesten schneidet eigentlich immer noch die string-Version mit dem verbesserten Allokator ab. COW ist nur dann besser, wenn Du oft (sehr oft!) kopierst, aber nicht veränderst.

    MfG Jester


Anmelden zum Antworten