Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > C/C++
You last visited: Today at 21:12

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Performance Problem mit Pointer-Array

Discussion on Performance Problem mit Pointer-Array within the C/C++ forum part of the Coders Den category.

Reply
 
Old   #1
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
Performance Problem mit Pointer-Array

So Leute, ich mal wieder

Heute geht es um etwas echt "heikles" und ich bin völlig ratlos, wieso das "so lange" dauert.

Ich habe drei (beteiligte) Klassen, die wie folgt zusammenhängen:

1. Die Klasse AalVariable speichert einen Wert (oder mehrere Werte je nach "Benutzung"). Das heißt ein Objekt der Klasse AalVariable speichert einen Wert in einem std::vector<void*>. Wobei es zusätzlich ein zweites Array gibt, welches den Typ des abgespeicherten Wertes (string/long long/double) enthält, damit der Wert später auch richtig gecastet werden kann.

2. Die Klasse AllocationHelper ist eine Klasse, die dabei hilft allozierten Speicher wiederzuverwenden (damit spare ich mir einige Tausend news/deletes).

3. Die Klasse Interpreter bekommt eine Reihe Befehle "zu geschmissen" und interpretiert diese. Momentan "nur" Die Grundrechenarten, das Abspeichern der Werte in Variablen (Dafür benutze ich Objekte der Klasse AalVariable) und Schleifen.

Beispielsweise diesen Pseudocode/AutoIt:
PHP Code:
$var=0
$var2
=0
while $var2<1000000
    $var
+=1
    $var2
+=1
WEnd 
Braucht meine Klasse von Interpreter rund 700ms.
Der AutoIt-Interpreter braucht 900ms.

Soweit so gut, aber nachdem mir diese 700ms noch viel zu lange vorkamen, habe ich einmal die einzelnen Code-Stücke gebenchmarkt und dabei ist mir etwas sehr komisches aufgefallen:

Das Parsen an sich dauert (für den kompletten Durchlauf) um die 50ms, also vollkommen ok.
Die Berechnungen/das Abspeichern selbst dauert auch nur etwas um die 50ms.

Das hat mich enorm stutzig gemacht also habe ich noch mehr gebenchmarkt und herausgefunden, dass der Flaschenhals (scheinbar?) bei meinem Hauptspeicher bzw. genauer gesagt beim Übertragungsweg liegt.

Dieses Stück Code (für alle Aufrufe also einen kompletten Durchlauf, ziemlich genau 3.000.000 Aufrufe) braucht um die 500ms:

PHP Code:
inline AalVariableInterpreter::getAalVar(const long long tmp)
{
    if(
currHierarchyLevel==0)
    {
        
auto it=globalVars.find(tmp);
        if(
it!=globalVars.end())
        {
            return 
it->second;
        }
        else
        {
            
AalVariabletmpVar=allocator.allocateAalVar();
            
globalVars[tmp]=tmpVar;
            return 
tmpVar;
        }
    }
    else
    {
        
//todo: implement later
        
return nullptr;
    }

mit diesem Code-Stück hole ich mir die Variable (alle Variablen sind mit long long durchnummeriert), sollte sie bereits deklariert worden sein aus "std::map<long long,AalVariable*> globalVars;", ansonsten hole ich mir über den AllocationHelper eine neue Instanz der Variable.

Wie erwartet funktioniert der Interpreter richtig und holt sich lediglich einmal (vor der While-Schleife) eine neue Instanz. Das heißt der Else-Zweig wird genau einmal ausgeführt.

Damit ist der Flaschenhals also dieses Stück Code:
PHP Code:

auto it
=globalVars.find(tmp);
if(
it!=globalVars.end())
{
    return 
it->second;

Am Anfang dachte ich es liegt an meiner map, dass der Zugriff so enorm lange braucht, also habe ich den Code dann testweise in einen Vektor umgeschrieben, also in etwa das:

PHP Code:
if(globalVars[tmp]!=nullptr)
{
    return 
globalVars[tmp];

Aber auch das hat mir "nur" 10ms eingespart (was auch zu erwarten war, weil die map ja nur aus 2 Variable besteht). Das heißt statt 500ms nimmt die Funktion nur noch 490ms in Anspruch, was mir immer noch viel zu viel ist.

Ohne dass ich es mit meinen eigenen Augen gesehen/ausprobiert hätte, würde ich sagen, dass realistsiche Werte irgendwo bei 50-100ms liegen sollten.

Aber egal was ich mache ich komme einfach nicht auf weniger.

Mein Code besitzt keinerlei Multithreading/Windows spezifischen Code.
Sowohl auf Linux als auch auf Windows ist die Funktion (bzw. das if) der Flaschenhals (bisher auf 3 Pcs getestet, 2x Windows, 1x Linux/Ubuntu).

Meine Header-Dateien/Klassen (unwichtige Methoden habe ich rausgenommen) sehen dabei wie folgt aus:

Interpreter.h

Aalvariable.h

AllocationHelper.h

Habt ihr eine Idee wieso der Flaschenhals ausgerechnet dort entsteht und sich auch nicht durch Vektoren beheben lässt? Gibt es vielleicht zu viele Cache-Misses? Kann ich mir aber auch nicht vorstellen, weil der benutze Speicher wohl sogar locker in ein Level 1/2 Cache passt (sind ja nur paar Zeilen).

Aber noch wichtiger als die Frage nach dem warum ist mir vor allem, wie behebe ich das bzw. wie mache ich den Code schneller/löse den Flaschenhals auf?

Edit:
Laut Taskmanager braucht mein Prozess 650K, sollte also sogar noch in einen Level 2/3 Cache reinpassen, theoretisch, wäre natürlich doof wenn genau immer dieser Bereich überschrieben werden würde.
Shadow992 is offline  
Old 09/05/2015, 10:26   #2
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
würde auf jedenfall einen vector benutzen.
Wieso benutzt du einen long long als index? ist langsamer und im zweifel wird dir bei nem uint32_t nach 4milliarden vars eh der speicher auslaufen.

was sagt denn z.b. der vs profiler?

eigtl sollte ein index return ziemlich flott sein, glaub eher, dass deine messungen i-wo mist bauen, also bei mir dauern 10.000.000 array querys ~4-6m, mit nem if ~14ms.

wie misst du denn?
schonmal den generierten asm code angeschaut?
kompilierst mit optimierungen?

edit:

kompilierste als debug? nen std::vector braucht bei mir @ debug auch ~600ms bei 10mio zugriffen, @ release immerhin nur ~17ms.
Dr. Coxxy is offline  
Thanks
1 User
Old 09/05/2015, 12:51   #3
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
Quote:
Originally Posted by Dr. Coxxy View Post
würde auf jedenfall einen vector benutzen.
Wieso benutzt du einen long long als index? ist langsamer und im zweifel wird dir bei nem uint32_t nach 4milliarden vars eh der speicher auslaufen.

was sagt denn z.b. der vs profiler?

eigtl sollte ein index return ziemlich flott sein, glaub eher, dass deine messungen i-wo mist bauen, also bei mir dauern 10.000.000 array querys ~4-6m, mit nem if ~14ms.

wie misst du denn?
schonmal den generierten asm code angeschaut?
kompilierst mit optimierungen?

edit:

kompilierste als debug? nen std::vector braucht bei mir @ debug auch ~600ms bei 10mio zugriffen, @ release immerhin nur ~17ms.
Der Long Long wird als Index benutzt, weil ich sowohl Variablen beim Parsen in Longs umwandeln lasse als auch die Zahlen selbst. Die Zahlen selbst will ich nicht auf int "runterschrauben". Aber deine Idee kam mir auch schon, dass long long Probleme machen könnte, deswegen habe ich auch das einmal Testweise ausprobiert, Einsparung lag ebenfalls im 10ms Bereich.

Ich benutze bisher für alle 3 Test (auf den verschiedenen Pcs) Gnu Gcc++.
Wobei das einmal Version 4.7, einmal 4.8 und einmal 5.1 war.

Die Map statt den Vektoren benutze ich deswegen, weil ich zwar jede Variable durchnummeriere, jedoch nicht relativ zum "Stack-Pointer" sondern global. Das heißt es kann sein, dass die erste globale Variable den Index 0 besitzt und die zweite globale (auf Grund von vielen Hierarchie-Änderungen wo lokale Variablen deklariert werden) den Index 10000. Damit hätte ich am Ende ein Array mit der Größe 10000, obwohl es eine Map mit 2 Einträgen auch getan hätte.

Daher bevorzuge ich die map-Variante.

Den generierten ASM-Code habe ich mir nicht angeschaut, das wollte ich erst als letzten Ausweg machen, weil das Projekt bisher schon 3000 Zeilen C/C++ Code umfasst.

Ich habe alle Optimierungsoptionen vom Gcc++ probiert, also -o, -o1, -o2, -o3 und -fexpensive-optimize (oder wie das genau heißt).

Die Unterschiede hat man wirklich gespürt, es gibt echt von Optimierungslevel zu Level merkliche Verbesserungen (in etwa 100-150ms pro Stufe). Aber trotzdem ist das Minimum bei rund 600-700ms.

Ich habe meine Tests jetzt noch einmal durchgeführt.
Auf den anderen 2 Pcs hatte ich "nicht so gut optimierten" Code getestet.

Jetzt nach erneutem Testen auf Linux, komme ich auf 60ms für das Interpretieren/Parsen/etc. des obigen Codes.

Das erscheint mir endlich realistisch und auch sehr gut.

Den 2. Windows-Pc kann ich leider nicht auf die Schnelle testen, der gehört meinem Freund, aber bei Gelegenheit werde ich das noch einmal testen.

Also zusammengefasst sieht die Lage jetzt so aus (die Tests beziehen sich auf eine abgespeckte Version):

Gnu Gcc++ 4.8 (oder 4.7?) auf Linux/Ubuntu mit -o2 als Optimierung läuft in genau 66ms, Release kompiliert, wobei die Hardware theoretisch schwächer ist (Laptop mit Intel i3 und dürfte sogar noch DDR2 Speicher haben)

Auf Windows mit 5.1.2 (glaub ich ist 5.1.2, könnte aber auch 5.1.0 sein) kompiliert das ganze Programm (ebenfalls in Release) mit rund 220ms. Die Hardware hier ist ein AMD mit rund 3.2GHz und 8Gb DDR3 Speicher.

Ich möchte es nicht ausschließen aber mir scheint da nicht die Hardware dran Schuld zu sein.

Ich lade die abgespeckte Exe hier mal hoch, die ich unter Windows kompiliert habe, die Ausgabe der gesamt benötigten Zeit steht hinter "Overall Processing: ". Wäre cool wenn das jemand mal austesten kann, damit ich ausschließen kann dass es an meiner Hardware liegt. Auf meinem Windows-Pc braucht sie in etwa 220ms. Dieselbe abgespeckte Version unter Linux kompiliert braucht 66ms.

Edit:
Virensystem war auch schon testweise ausgeschalten während den Tests, damit ich ausschließen kann dass da nichts reinpfuscht.

Edit2:
Achja die Exe hat kein "system(pause)" o.ä. am Ende, das heißt am besten startet ihr sie über cmd, damit ihr die Ausgabe auch sehen könnt.

Edit3:
Beim Pc meines Bruders läuft die hier hochgeladene Exe in 120ms durch, auch das erscheint mir schlecht. Vor allem weil er einen sehr aktuellen Pc hat.

Scheinbar hat die Windows-Version von 5.1 einen/mehrere Bugs? Oder wie kann ich mir sonst derartig langsame Zeiten erklären, obwohl die Hardware potenter ist?

Edit4:
Die "größere" Version läuft unter Linux am Laptop ebenfalls schneller als am Pc, aber braucht trotzdem noch 400ms, was meiner Meinung nach immer noch zu viel ist.

Ich kann mir das einfach nicht erklären, warum läuft der Code so enorm langsam?
Ich könnte prinzipiell den Source hier hochladen, weil ich ihn später eh Open-Source machen will, aber ich bezweifle, dass sich jemand 3000 Zeilen mit sehr sporadischen Kommentaren antun will.
Attached Files
File Type: zip AAL_ByteCode_interpreter.zip (311.8 KB, 7 views)
Shadow992 is offline  
Old 09/05/2015, 13:58   #4
 
Dr. Coxxy's Avatar
 
elite*gold: 0
Join Date: Feb 2011
Posts: 1,206
Received Thanks: 736
probier mal statt nem vektor nen raw array.
und wie misst du die zeit?

auf nem i7-2600k - aber in ner vm.

edit:
-wieso hast du eine globale var map wenn du lokale variablen hast?
das klingt mir bissle nach design fail.

-den generierten asm code - reichts ja für die eine stelle anzugucken - das sollten eigtl nur 5-6 zeilen bei nem vector/raw array sein. mit ida und der object datei solltest du das easy finden - bzw. kannst dir afaik vom gcc auch den erzeugten asm code direkt mit c++ in kommentaren ausgeben lassen.

-probier mal unter windows visual studio anstatt gcc.
Dr. Coxxy is offline  
Thanks
1 User
Old 09/05/2015, 14:09   #5
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
Quote:
Originally Posted by Dr. Coxxy View Post
probier mal statt nem vektor nen raw array.
und wie misst du die zeit?

auf nem i7-2600k - aber in ner vm.
Meine Main sieht wie folgt aus:

PHP Code:
int mainint argc, const charargv[] )
{
    
BytecodeLineb=new BytecodeLine;
    
b->arg1="$0";
    
b->arg1Long=0;
    
b->arg2="1";
    
b->arg2Long=1;
    
b->assignVar="$0";
    
b->assignVarLong=0;
    
b->commandType=TOK_OP_ADD;
    
b->type=LINE_COMMAND;

    
BytecodeLineb2=new BytecodeLine;
    
b2->arg1="10";
    
b2->arg1Long=10;
    
b2->arg2="1";
    
b2->arg2Long=1;
    
b2->assignVar="$0";
    
b2->assignVarLong=0;
    
b2->commandType=TOK_OP_ADD;
    
b2->type=LINE_ASSIGN;
    
#if SHOW_TIMINGS == 1
        
auto startAll std::chrono::steady_clock::now();
    
#endif

    
std::string toParse=readStringFile("out.aal1");
    
Interpreter interpret(toParse);
    
//interpret.interpretAllLines();


    
std::string tmp="126543";
    
interpret.interpretLine(b2);
    for(
int i=0;i<1000000;i++)
    {
       
interpret.interpretLine(b);
    }


    
#if SHOW_TIMINGS == 1
        
auto endAll std::chrono::steady_clock::now();
        
auto diffAll endAll startAll;
        
std::cout << "Overall processing: " << std::chrono::duration <doublestd::milli> (diffAll).count() << "ms" << std::endl;
    
#endif


    
for(auto it=interpret.globalVars.begin();it!=interpret.globalVars.end();++it)
    {
        
std::cout<< it->first <<" = "<< *((it->second)->getStringPointer(0))<<std::endl;
    }


    return 
0;

Das heißt gemessen wird per chrono.
Und 120ms erscheint mir auch recht viel, weil das ja nur die abgespeckte Version ist, selbst in einer VM, vor allem weil deine CPU ja Virtualisierung auf Prozessor-Ebene können sollte.

Der Code sollte eigentlich enorm schnell durchlaufen, denn das Einzige, was in dieser Schleife passiert ist das:

PHP Code:
void Interpreter::interpretLine(BytecodeLinebytecode)
{
    switch(
bytecode->type)
    {
      
// die anderen cases werden beim testcode nie ausgeführt, habe ich auch per cout validiert
    
case LINE_COMMAND:
        
interpretCommand(bytecode);
        break;
    default:
        break;
    }

und InterpretCommand sieht genau so aus:

PHP Code:
    char type=TYPE_LONG;

    
double tmpDouble1;
    
double tmpDouble2;

    
long long tmpLong1;
    
long long tmpLong2;

    
AalVariableold1=tmpArg1Var;
    
AalVariableold2=tmpArg2Var;
    
AalVariableassign;

    
//tmpArg2Var->setValue(bytecode->arg2,TYPE_STRING);

    
if(bytecode->assignVar[0]=='*')
    {
        
assign=getAalVar(bytecode->assignVarLong);
    }
    else
    {
        
assign=getAalVar(bytecode->assignVarLong);
    }

//... Berechnung, also add 
Unter Linux braucht das Abfragen der Variablen "nur" 17-20ms von den insgesamt 66ms. Damit kann ich leben. Der Rest gehört wohl noch in das Optimieren des Berechnung-Codes. Da kann ich sicher noch ein paar ms rausholen, wobei 60ms und davon 20ms für die map vollkommen ok ist.

Testen tu ich das, indem ich einfach die Berechnungen etc. auskommentiere.

Edit:
"-wieso hast du eine globale var map wenn du lokale variablen hast?
das klingt mir bissle nach design fail."

Diese eine Map ist für alle globalen Variablen Zuständig, anschließend wird es (bald) auch eine 2. Map (eher sogar vector<vector<map<>>>) geben, die die Variablen Hierarchie bezogen verwaltet, ähnlich zu einem Stack.

Diese Unterscheidung zwischen Global und Lokal mache ich aus dem einfachen Grund, da ich später auch Multi-Threading erlauben will und dazu die Variablen in der globalen Map über mehrere Interpreter Instanzen hinweg sharen will. Die lokalen Variablen hingegen werden nicht gesharet.

Ob das wirklich alles so hinhaut muss ich noch testen, in meinem Kopf sieht das aber gut aus. Und selbst wenn ich das nicht trenne, bleibt mein Problem ja bestehen.

Edit2:
Ich glaube ich werde es mal mit dem MS-Compiler probieren und dann noch einmal schauen was dabei rauskommt.
Shadow992 is offline  
Old 09/05/2015, 14:30   #6
 
Padmak's Avatar
 
elite*gold: 58
Join Date: Jun 2008
Posts: 2,311
Received Thanks: 8,420


i7-2700k, nicht VM sondern auf meinem normalen Rechner mit Windows 7
Kann dir nicht helfen, aber zumindest ein Messergebnis anbieten

Padmak
Padmak is offline  
Thanks
1 User
Old 09/05/2015, 15:40   #7
 
elite*gold: 198
Join Date: Mar 2011
Posts: 835
Received Thanks: 263
Windows 10 64bit




ƬheGame is offline  
Thanks
1 User
Old 09/05/2015, 16:10   #8
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
Dankeschön Leute.
Die Zeiten sind auf jeden Fall alle besser als bei meinem Pc (vielleicht sollte ich doch mal die Ram-Riegel überprüfen lassen) und zwar um bis zu dem Doppelten.

Warum mein "großes" Programm "so langsam" auf Linux läuft habe ich mittlerweile herausgefunden, dieses Mal war nicht das getAalVar Schuld, sondern die interne Abarbeitung meiner Schleife, da Bedarf es wohl noch einiges an Optimierungen.

So wie es aussieht ist die "langsame" Codeerzeugung einfach ein Problem meiner aktuellen Gcc Version oder aber allgemein von Gcc auf Windows.

Das werde ich ja bald feststellen, sobald die 7Gb Visual Studio installiert sind.

Auf Linux hingegen läuft alles (außer halt die Schleife) schon einmal sehr fix. Damit ist dieses Problem auch geklärt, ob ich es beseitigen kann ist eine andere Frage (vielleicht ist das Problem auch ein Windows-Speicherverwaltungs-Problem?) auf jeden Fall habt ihr mir sehr geholfen und jetzt kanns endlich guten Gewissens weitergehen.

Edit:
Das Problem ist gefunden!


Ich werde verrückt, tatsächlich hatte das Ganze genau gar nichts mit vector/map zu tun oder gar mit irgendwelchen langsamen Hauptspeichern.
Das Problem kam ganz wo anders her.

Als ich anfing die Schleifen (besonders den Vergleichs-Operator) näher anzuschauen, bin ich auf etwas sehr komisches gestoßen.

In meiner "Sprache" soll alles was ungleich 0 ist (egal ob String, Long Long oder Double) True sein und der Rest False. Damit ich damit aber später einheitlich arbeiten kann "wandelt" meine Schleifenbedingung das Ganze erst in einen String um, das Umwandeln einiger Tausend Werte dauert (auf Grund von meinem AllocationHelper) nur wenige ms.

Das Problem war ganz anderer Natur.
Meine Klasse AalVariable besitzt eine Methode, die wie folgt aufgebaut ist:

PHP Code:
void setValue(const std::stringvalchar typeint idx=0); 
Aus Performance-Gründe lasse ich hier eine const Referenz übergeben.
In meinem Vergleichs-Operator, lasse ich dann das machen:

PHP Code:
            if(tmpLong1 == tmpLong2)
            {
                
assignVar->setValue("1"assignVar->valueType[0], 0);
            }
            else
            {
                
assignVar->setValue("0"assignVar->valueType[0], 0);
            } 
Das heißt ich setze den Wert je nachdem ob die Bedingung erfüllt ist auf "1" oder auf "0".
Der Vergleichsoperator-Code war auch Teil der Switch-Case-Anweisung, in welcher mein Add-Befehl stand.

Zum Testen/Benchmarken habe ich NUR den Add-Befehl auskommentiert, da ich ja bei den anderen cases zum Absichern überall couts hatte (welche auch nie aufgerufen wurden).

Wie es mir scheint hat Gcc bei meinem Vergleichsoperator immer gesagt:
"Huh was machst denn du da? Ich will eine const Referenz auf einen String und keine 2 Char-Arrays. Naja was solls die sind sowieso const also lege ich am Anfang deiner Methode einfach 2 Strings an, einmal für 0 und einmal für 1. Du benutzt diese konstanten Werte ja auch in anderen Case-Zweigen."

Das Anlegen dieser Strings dauerte natürlich enorm lange (im Vergleich zum reinen Parsen/Interpretieren). Da die Strings bei jedem Methoden-Aufruf neu erstellt wurden und bei 3.000.000 Aufrufe das schon einige Male sind, wurde das Ganze natürlich unnötig langsam.

Meine Lösung war jetzt sehr simpel und gehört eigentlich auch zum guten Programmierstil dazu (ich glaube besonders nach dem Ereignis jetzt werd ich das auch immer so machen ).

Ich habe der Interpreter-Klasse einfach 2 const strings spendiert, also so:
PHP Code:
private:
    const 
std::string STR_TRUE="1";
    const 
std::string STR_FALSE="0"
und meinen Code des Vergleichsoperators in das abgewandelt:
PHP Code:
            if(tmpLong1 == tmpLong2)
            {
                
assignVar->setValue(STR_TRUEassignVar->valueType[0], 0);
            }
            else
            {
                
assignVar->setValue(STR_FALSEassignVar->valueType[0], 0);
            } 
Und voila plötzlich läuft mein "großer" Code nicht mehr wie vorher am Windows-Pc in 500-600ms, sondern in 120ms.

Das ist auch ungefähr die Größenordnung, die ich erwartet hatte, ich wollte zwar ursprünglich die 100ms Marke knacken, aber das bekomme ich wohl nur mit allgemeinen kleinen Optimierungen hin.

Mein Code wird jetzt auf jeden Fall schnell genug interpretiert.
Herzlichen Dank noch einmal für die Hilfe an alle.
Shadow992 is offline  
Old 09/08/2015, 01:35   #9

 
Delinquenz's Avatar
 
elite*gold: 0
Join Date: Jan 2009
Posts: 1,160
Received Thanks: 232
Mit welchen Flags hast du das kompiliert? Ich kenne mich ehrlich gesagt nicht so gut mit Optimierung aus, aber es wäre schon interessant zu wissen, dass so ein Flaschenhals nicht wegoptimiert wird.
Delinquenz is offline  
Old 09/08/2015, 08:33   #10
 
elite*gold: 198
Join Date: Mar 2011
Posts: 835
Received Thanks: 263
Quote:
Originally Posted by Delinquenz View Post
Mit welchen Flags hast du das kompiliert? Ich kenne mich ehrlich gesagt nicht so gut mit Optimierung aus, aber es wäre schon interessant zu wissen, dass so ein Flaschenhals nicht wegoptimiert wird.
Es wäre schlimm, wenn sowas optimiert würde. Der Compiler ist nicht dazu da schlechten Code in guten umzuwandel. Da könnte man ja sonst am Ende nur noch raten, was für ein Programm dabei rauskommt.
ƬheGame is offline  
Old 09/08/2015, 13:25   #11
 
Shadow992's Avatar
 
elite*gold: 77
Join Date: May 2008
Posts: 5,430
Received Thanks: 5,878
Quote:
Originally Posted by Delinquenz View Post
Mit welchen Flags hast du das kompiliert? Ich kenne mich ehrlich gesagt nicht so gut mit Optimierung aus, aber es wäre schon interessant zu wissen, dass so ein Flaschenhals nicht wegoptimiert wird.
Ich hatte es mit allerlei Optimierungen ausprobiert und auch ohne Optimierung.
Ich meine diese Art von Optimierung ist ja wirklich sehr "basic", weil der Compiler mir die Arbeit des "für verschieden Case-Zweige ständig neu erzeugen von den Strings" abnehmen will. Theoretisch, wenn ich nur die Möglichkeit gehabt hätte das "fest" ins Programm zu schreiben, wäre das auch wirklich eine sehr gute Optimierung gewesen, weil der String dann nicht 3-5x erstellt werden muss, sondern lediglich genau einmal.

Im Nachhinein erscheint mir diese "Optimierung" (wenn es eine ist) daher sogar relativ klug.
Aber sie hat halt leider das "Optimieren" allgemein verschlimmert.
Shadow992 is offline  
Reply


Similar Threads Similar Threads
char array vom pointer mit srcpy changen
04/09/2015 - C/C++ - 10 Replies
Hey zusammen, also habe ein kleines problem das grad unnormal nervt:rtfm: Habe in einem game ein pointer der auf ein char array zeigt der pointer ist DWORD* F = (DWORD*)0x0076BBD8; // hier der pointer auf dem pointer ist jetzt ein char array drauf, nehmen wir einfach als beispiel "hey"
Pointer/Pointer finden (problem)
01/08/2014 - AutoIt - 7 Replies
Hallo Leute. Bin schon seid einigerzeit am suchen bzw. rumtesten wie ich "die Adresse der Koordinaten der hingeklickten Stelle" finden kann ... :S will ein bot erstellen und damit er im hintergrund aufen kann brauche ich: Meine character coordinaten/Pointer ( Habe ich) und jetzt muss ich die coordinaten der hingeklickten stelle finden bzw. die adresse aber iwie klappt nix x,x ... finde immer einige adressen und den pointer meines charas , der Pointer der coordinaten meines charas...
Multilevel Pointer hacken per Array [Fehlersuche]
05/06/2012 - AutoIt - 12 Replies
Hi Den Wert folgendes Level4-Pointers möchte ich mit einem Autoit-Script hacken: Base: 1073EF88 Offset1: 1C Offset2: 10 Offset3: 4 Offset4: DE4 Dazu habe ich dieses Tutorial gefunden, was beschreibt, wie man den Pointer per Array verwendet:
[C] Pointer auf Array
08/26/2009 - General Coding - 3 Replies
Hallo, Ich habe folgendende Pointer deklariert: char *Menu0 = {"Gerd","Egon","Juergen&q uot;,"Karl","Hans-Dieter",&quo t;Hans-Guenther"}; char *Menu1 = {"Anna","Inge","Franziska ","Lisa","Maria"}; usw..



All times are GMT +1. The time now is 21:13.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.