Ich habe eine Funktion, die für ihre Berechnungen einige interne Zwischenspeicher benötigt (einige Matrixoperationen), und ich weiß, dass diese Funktion häufig aufgerufen wird (etwa jede Millisekunde während der Laufzeit des Programms). Mein Bauchgefühl sagt mir, dass es besser ist, diese temporären Variablen statisch zu deklarieren, so dass es nicht so viel Verwaltungsaufwand gibt, sie bei jedem Aufruf der Funktion immer wieder neu zu erstellen. Ich muss sie trotzdem jedes Mal initialisieren, wenn die Funktion aufgerufen wird, so dass sie für funktionale Zwecke nicht benötigt werden. Ich bin mir bewusst, dass die statische Sicherheit die Fadensicherheit zerstört, aber das ist hier kein Problem.
Da Wissen normalerweise besser ist als jedes Bauchgefühl, würde ich gerne wissen, wie der "richtige" Umgang mit diesem Fall ist.
%Vor%oder
%Vor%Es gibt keinen Unterschied. Es ist kein Code erforderlich, um ein nicht initialisiertes Array zu erstellen.
Bei einem statischen Array ist der Speicher reserviert und jederzeit verfügbar. Im Falle eines automatischen Arrays befindet es sich auf dem Stapel, und alles, was zum "Erstellen" benötigt wird, ist es, den Stapelzeiger zu bewegen, was sowieso beim Eintritt in die Funktion passieren wird.
(Und eines Tages wirst du versuchen, diese Funktion in einem Multithread-Programm zu benutzen, und die statische Version wird gelegentlich Unterbrechungen erleiden, die dich zu Alkohol und Drogen treiben. Es ist das Risiko einfach nicht wert.)
Ich würde es definitiv auf die einfachste und lesbarste Weise schreiben. Einmal pro Millisekunde klingt wie eine sehr selten run-Funktion zur Mikrooptimierung.
Sobald es funktioniert, benchmarken Sie es. Entscheiden Sie, ob die Leistung gut genug ist. Wenn nicht, optimieren und benchmarken Sie erneut. Nicht beugen Sie sauberen Code ohne feste Zahlen aus der Form, um Ihre Entscheidung zu sichern.
Sie versuchen eine Mikrooptimierung ohne Benchmarking, was allgemein als schlecht angesehen wird. Sie sollten immer Benchmarking. Wie können Sie sonst sicher sein, dass jeder Optimierungsversuch funktioniert hat?
Es ist unwahrscheinlich, dass Sie dadurch etwas erreichen, und die Lesbarkeit und Wartbarkeit des Codes sollten an erster Stelle stehen.
Das Zuweisen von Stapelvariablen entspricht nicht dem Zuweisen von Heap-Variablen. Alles was passiert, ist, wenn der Stapelzeiger weit genug nach unten bewegt wird, um den gesamten von der Funktion benötigten Speicher zuzuweisen. Es gibt keinen Overhead bei der Zuordnung von einer oder einhundert Variablen in einem Stapelrahmen. Der Stapelzeiger wird bereits beim Aufruf der Funktion verschoben, auch wenn es keine Variablen gibt (um aufzuzeichnen, wo zu usw. zurückzukehren ist).
Bei SPARC insbesondere im 64-Bit-Modus ist der statische Fall langsamer. Der Zugriff auf eine globale Variable (die statische ist, ist nur der Name, der auf den Umfang der Funktion beschränkt ist) benötigt 5 Anweisungen mit 3 Register, in Ihrem Fall 10 Anweisungen, nur um die Adresse der Arrays zu erhalten. Die nicht statische Version hat, wie bereits erwähnt wurde, keinen Overhead, da der Frame in jedem Fall aufgebaut wird, wenn der Stack-Pointer um 16 Bytes oder 200 Bytes wächst. Aber seien Sie vorsichtig, wenn Sie Ihr Array initalisieren, dies kann ein verstecktes memset ergeben, das teuer sein kann.
%Vor%macht wahrscheinlich 1 oder 2 memcpy oder memset Aufrufe, um die Arrays zu initialisieren.
Das Reservieren von Speicherplatz für Variablen mit automatischer Speicherdauer bedeutet, dass nur der Stapelzeiger verkleinert wird. Solange dies nicht die einzigen lokalen Variablen sind, entsteht kein Overhead.
Was die Leistung beeinträchtigen könnte, ist, dass die Variablen, die dem Stack zugewiesen wurden, relativ zum Stack- oder Basiszeiger adressiert werden müssen, sodass die Verwendung von static
die Leistung leicht verbessern kann.
Wie immer, benchmarken Sie den Code, um sicherzugehen.
Tags und Links c