free(...) dauer sehr lange



  • Moin,

    also ich lese mit meiner Funktion eine Zip-Datei mit 40000 Einträgen aus. Mein kompletter Code braucht 3,2 Sekunden um die Datei auszulesen und das Inhaltsverzeichnis mit _strdup(..) je einzelnen Eintrag in einen String zu schreiben. Am Ende der Funktion muss der Speicherbereich ja wieder freigegeben werden als rufe ich in eienr for-Schleife die free-Funktion auf. Jetzt dauert das ganze 3,6 Sekunden um mit free den Speicher freizugeben. Wie ist das möglich, dass eine so simpele Zeile Code länger dauert als meine zig hundert Zeilen Code um die Datei auszulesen?

    Hier mal der Quellcode, so dauert das ganze Programm 3,2 Sekunden

    if(zip->intern.zinfoall.pzentryinfo){
    		u_int		i;
    		zentryinfo_t	*pzentryinfo;
    		pzentryinfo = zip->intern.zinfoall.pzentryinfo;
    		for(i = 0; i < zip->intern.zinfoall.anzahl_zipentries; i++){
    			if(pzentryinfo->entry_name){
    //				free(pzentryinfo->entry_name);	//ausgeschaltet
    			}
    			pzentryinfo += 1;
    		}
    		free(zip->intern.zinfoall.pzentryinfo);
    	}
    

    So dauert das ganze Programm 6,8 Sekunden

    if(zip->intern.zinfoall.pzentryinfo){
    		u_int		i;
    		zentryinfo_t	*pzentryinfo;
    		pzentryinfo = zip->intern.zinfoall.pzentryinfo;
    		for(i = 0; i < zip->intern.zinfoall.anzahl_zipentries; i++){
    			if(pzentryinfo->entry_name){
    				free(pzentryinfo->entry_name);
    			}
    			pzentryinfo += 1;
    		}
    		free(zip->intern.zinfoall.pzentryinfo);
    	}
    

    Wohlgemerkt da hängen noch zig Hundert Zeilen Code davor. Hinter der if-Abfrage ist dann Schluss, es wird nur noch ein Zeitwert festgehalten und ausgegeben um die Performance zu bestimmen



  • Das liegt daran, dass dein strdup (nicht Standard) jeweils einmal malloc bemüht, was genau ein free() benötigt.
    Das dauert nun mal.
    Baue dir einen eigenen Memory-Manager oder suche dir was, das wenig malloc und somit wenig free aufruft, üblicherweise reservierst du vorab 1x per malloc die geschätzte Gesamtgröße, und rufst dann nur noch 1x free auf. Das sollte dann deutlich schneller ablaufen.



  • Hey,

    ich kann die benötgte Grösse eines Namenseintrags nicht abschätzen, einmal ist er 2 Byte gross ein andersmal 500 oder über 1000. Nicht einmal die Anzahl der Einträge ist abschätzbar. Das ist hat mal so bei Zip-Dateien, da kann sonstwas drin stehen. Zip64 kann sogar mehr als 2hoch32 Eintrage sprich 2hoch64 beinhalten. Mich hat erstmal interessiert warum 40000 Aufrufe von free länger dauern, als zig Hundert Zeilen Code, die darüberhinaus auch noch 40000 Aufrufe von _strdup beeinhalten.

    Ich hatte testweise auch mal mit malloc einmalig Speicher erzeugt der 40000*1024 gross war, den hab ich dann alle 1024 Byte mit strcpy mit den Einträgen gefüllt. Das Programm lief dann 3,0 anstelle von 3,2 Sekunden. Ist mir echt unerklärlich dass 40000 stcpy anstelle _strdup nur 0,2 Sekunden ausmacht. Aber so ein simpeles free, wenn man es 40000 anwendet 3,6 Sekunden braucht.



  • Ok,

    Ursache des Effekts gefunden. Ich habe mein Proframm immer mit dem Debugger im Debugger-Build gestartet. Im Release-Build ist kein signifikanter Unterschied beim Weglassen von free spürbar. Das Programm benötigt immer ca. 3.12 Sekunden.


Log in to reply