Deklarieren von Variablen hinter der Schleife oder innerhalb der Schleife?

 
   string st = "";
   for (int i = 0; i < 1000; i++)
   {
      st = i;
      ...
   }

oder

   for (int i = 0; i < 1000; i++)
   {
      string st = i;
      ...
   }

Gibt es einen Unterschied? angesichts aller Optimierungen des mql5-Compilers?

 
pivalexander:

oder

Gibt es einen Unterschied? angesichts aller Optimierungen des mql5-Compilers?

Bei der Kompilierung gibt es keinen Unterschied, Sie können also die zweite Option verwenden.
 

Ich persönlich bevorzuge die erste Variante.

Für den Fall der Fälle. Der Compiler ist vielleicht schlau genug, nicht jedes Mal Speicher zuzuweisen, aber im ersten Fall gebe ich es explizit an, aber im zweiten Fall ist es ein implizites Ergebnis des Compilers, weil die Variable gemäß der Sprachlogik innerhalb eines Blocks erstellt werden muss und beim Verlassen des Blocks wieder entfernt werden muss.

Und die Gleichsetzung von int mit string ohne Transformation ist schlechte Praxis.

 
pivalexander:

Gibt es einen Unterschied? angesichts aller Optimierungen des mql5-Compilers?

Hören Sie nicht darauf, dass es keinen Unterschied gibt. Verwenden Sie nur die erste Option, es gibt einen Unterschied. Ich habe den Disassm von MCL allerdings nicht studiert.

 
Georgiy Merts:

Ich persönlich bevorzuge die erste Variante.

Für den Fall der Fälle. Der Compiler ist vielleicht schlau genug, nicht jedes Mal Speicher zuzuweisen, aber im ersten Fall gebe ich es explizit an, aber im zweiten Fall ist es ein implizites Ergebnis des Compilers, weil die Logik der Sprache darin besteht, eine Variable innerhalb eines Blocks zu erstellen, und wenn Sie den Block verlassen, muss sie gelöscht werden.

Und int mit string gleichzusetzen, ohne es zu konvertieren, ist schlechte Praxis.

George hat Recht, es ist nicht garantiert.

Und wir erhalten eine Verzerrung der impliziten Umwandlung von "Zahl" in "String".


Und genau so werden wir die Unbestimmtheit und die Verzerrung los.

for (int i = 0; i < 1000; i++)
   {
      static string st = IntegerToString(i);
      ...
   }
 
Georgiy Merts:

Ich persönlich bevorzuge die erste Variante.

Für den Fall der Fälle. Der Compiler ist vielleicht klug genug, nicht jedes Mal Speicher zuzuweisen, aber im ersten Fall gebe ich das explizit an, aber im zweiten Fall ist es ein implizites Ergebnis der Arbeit des Compilers

Machst du Witze? Das ist für den Compiler eine so triviale Situation, dass es keinen Grund gibt, darüber zu reden. Vielleicht bist du so paranoid, dass du einfach in Assembler programmieren musst. Obwohl selbst das heutzutage schon sinnlos ist. Du wirst dich anstrengen müssen, um die Optimierung moderner Compiler zu schlagen.

p.s. Vielleicht war ich ein bisschen aufgeregt über die Trivialität im Falle des String-Puffers. Aber sie wird in MQL garantiert gespeichert, nicht nur innerhalb der Schleife, sondern auch zwischen Funktionsaufrufen. Dieses Thema wurde hier mehr als einmal diskutiert
 

Hören Sie nicht auf sie, sie werden Ihnen hier viel darüber erzählen ))

// c++
#include <iostream>
#include <string>
using namespace std;

void* operator new(size_t sz) {
    void *ptr = std::malloc(sz);
    if (ptr)
        return ptr;
    else
        throw std::bad_alloc{};
}


int main() {
        for (uint i = 0;  i < 3;  ++ i) {
                string s;
                char buf[10];
                sprintf(buf, "%u", i);
                s = "sfjhidfsrtea111";
                s += buf;
                cout << s << '\n';
        }
}

Ich kompiliere gcc -O3, führe es unter dem Debugger aus, setze einen Haltepunkt bei operator new und erhalte drei Aufrufe. Dasselbe gilt für Clang.

Hinweis: Wenn die Zeichenfolge aus der Schleife genommen wird, erhalte ich einen Aufruf.

 
Alexey Navoykov:

Machst du Witze? Das ist eine so triviale Situation für einen Compiler, dass es keinen Grund gibt, darüber zu reden. Wenn du so paranoid bist, kannst du Code rein in Assembler schreiben. Aber selbst das wird heutzutage sinnlos. Du wirst dich anstrengen müssen, um die Optimierung moderner Compiler zu schlagen.

p.s. Vielleicht war ich ein bisschen aufgeregt über die Trivialität hier, weil ich über den String-Puffer spreche. Aber sie wird in MQL garantiert gespeichert, nicht nur innerhalb der Schleife, sondern auch zwischen Funktionsaufrufen. Dieses Thema wurde hier mehr als einmal diskutiert

Nein, das bin ich nicht.

Natürlich sollte ein normaler Compiler in diesem Fall eine Variablendeklaration innerhalb einer Schleife nach außen bringen.

Ich denke einfach, dass man dem Compiler und sich selbst immer vertrauen sollte. Es ist ein Compiler-Standard, dass eine lokale Variable erstellt wird, wenn sie deklariert wird, und entfernt wird, wenn der Block, in dem sie deklariert wurde, beendet wird. Sie sollten sich also in erster Linie auf dieses Prinzip konzentrieren und nicht darauf warten, dass der Compiler Ihren Code für Sie verbessert.

Es geht nicht um Effizienz (moderne Compiler liefern wirklich sehr hochwertigen Code), sondern um das Denkschema der Programmierer. Wenn ich mir den Quellcode von Kodobase ansehe, frage ich mich oft, wie viele kleine und einfache, aber potenziell gefährliche Fehler er enthält. In diesem Fall ist es noch nicht sehr kritisch, es kann höchstens passieren, dass das Programm ein bisschen langsamer arbeitet. Echte Fehler könnten viel schwieriger sein.

 
Vict:

Hören Sie nicht auf sie, sie werden Ihnen hier viel darüber erzählen ))

Ich kompiliere gcc -O3, führe es unter dem Debugger aus, setze einen Haltepunkt bei operator new und erhalte drei Aufrufe. Dasselbe gilt für Clang.

Wenn die Zeichenkette aus der Schleife herausgenommen wird, erhalte ich also einen Aufruf.

Es ging nicht anders, denn Sie selbst haben die Optimierung durch Haltepunkte behindert. Das Wesen der Optimierung besteht darin, dass sie die Logik des Algorithmus nicht verändern sollte. Deshalb kann er nicht explizit erkannt werden. Wenn es dort einen Haltepunkt gibt, hat der Compiler natürlich kein Recht, diesen Code herauszuschneiden. Haben Sie angenommen, dass der Compiler den Haltepunkt überspringen kann? )

Sie können die Optimierung nur durch Kompilieren des Codes oder durch Messen seiner Leistung feststellen, also sollten Sie das als Erstes tun. Und beruhigen Sie sich)

 
Warten auf die Messungen)
 
Alexey Navoykov:

Es ging nicht anders, weil Sie selbst die Optimierung durch Sollbruchstellen behindert haben. Der Sinn der Optimierung ist, dass sie die Logik des Algorithmus nicht verändern darf. Deshalb kann er nicht explizit erkannt werden. Wenn es dort einen Haltepunkt gibt, hat der Compiler natürlich kein Recht, diesen Code herauszuschneiden. Haben Sie damit gerechnet, dass der Compiler den Haltepunkt überspringt? )

Sie können die Optimierung nur durch Kompilieren des Codes oder durch Messen seiner Leistung feststellen, also sollten Sie das als Erstes tun. Und beruhigen Sie sich)

Mann, das ist einfach nur dumm, was gibt es da zu kommentieren, ein komplettes Missverständnis, wie der Debugger funktioniert.

Über die Geschwindigkeit - Speichermanager ist nicht so dumm, und nicht die Tatsache, dass es das Betriebssystem fragen, kann früher zugewiesen overuse. Im Allgemeinen können Sie es verwenden, wie Sie wollen, es liegt an Ihnen. Aber Sie sollten andere nicht davon überzeugen, zumindest solange Sie keine konkreten Beweise liefern.