In C zeigt die Verwendung von statischen Variablen in einer Funktion, damit es schneller geht?
Meine Funktion aufgerufen wird, werden Tausende Male. Wenn ich will, um es schneller zu machen, wird die änderung der lokalen Funktions-Variablen static sein? Meine Logik dahinter ist, dass, da statische Variablen sind persistent zwischen Funktionsaufrufen, die Sie zugeordnet sind, nur die erste Zeit, und daher, jeder weitere Anruf wird nicht reserviert Speicher für Sie und wird schneller geworden, weil die Speicherreservierung Schritt ist nicht getan.
Auch, wenn die oben genannten wahr ist, dann wäre die Verwendung von globalen Variablen statt Parameter werden schneller zum weiterleiten von Informationen an die Funktion jedes mal aufgerufen wird? ich denke, dass Platz für Parameter zugeordnet ist auch bei jedem Aufruf, damit die Rekursion (das ist, warum die Rekursion verbraucht mehr Speicher), aber da meine Funktion nicht rekursiv ist, und wenn meine Argumentation richtig ist, dann ausziehen der Parameter wird in der Theorie machen Sie es schneller.
Ich weiß, diese Dinge, die ich tun möchte, sind schrecklich Programmierung Gewohnheiten, aber bitte, sagen Sie mir, wenn es klug ist. Ich werde es trotzdem versuchen, aber bitte geben Sie mir Ihre Meinung.
- Nicht optimieren code VOR profiling!...
- stackoverflow.com/questions/3730000/...
- Tun in der Regel schlechte Dinge zu erreichen, die kaum marginale SpeedUp für eine Funktion, die aufgerufen wird Tausende Male ist eine wirklich schlechte Idee. Wenn Sie können, sparen Sie vielleicht 10ns pro Funktionsaufruf für eine Funktion, die aufgerufen wird Tausende Male...Sie gespeichert haben einige Vielfache von 10 Mikrosekunden, das ist trivial, es sei denn Sie arbeiten auf einem harten Echtzeit-system und haben ein entscheidendes problem mit der Zeit schneiden.
- für alle, die darauf hindeutet, einen profiler: wo bekomme ich einen solchen? insbesondere eine für x86_64 GCC C.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Aufwand der lokalen Variablen ist null. Jedes mal, wenn Sie eine Funktion aufrufen, die Sie bereits jetzt den stack für die Parameter, Rückgabewerte usw. Hinzufügen von lokalen Variablen bedeutet, dass Sie hinzufügen eine etwas größere Zahl auf den stack-pointer (eine Zahl, die berechnet wird zur compile-Zeit).
Auch lokale Variablen sind wahrscheinlich schneller wegen cache-Lokalität.
Wenn Sie nur den Aufruf der Funktion "Tausende" Male (nicht Millionen oder Milliarden), dann sollten Sie sich bei Ihrem Algorithmus für die Optimierung Möglichkeiten nach, die Sie ausgeführt haben, einen profiler.
Re: cache-Lokalität (Lesen Sie hier mehr):
Häufig Zugriff auf Globale Variablen haben vermutlich die zeitliche Lokalität. Sie können auch kopiert, um ein register während der Ausführung der Funktion, aber geschrieben wird zurück in den Speicher (cache) nach einer Funktion gibt (sonst würden Sie nicht zugänglich sein, alles andere; Register haben keine Adressen).
Lokale Variablen haben in der Regel sowohl zeitliche und räumliche Lokalität (Sie bekommen, dass, aufgrund der erstellt wird, auf dem stack). Zusätzlich, Sie auch sein mögen "zugeteilt", die direkt auf die Register und nie werden in den Speicher geschrieben.
sub sp, 20
undsub sp, 24
, die überhaupt keinen Unterschied.sub sp, 20
undsub sp, 24
, die überhaupt keinen Unterschied.Der beste Weg, um herauszufinden, ist, tatsächlich ein profiler. Dies kann so einfach wie das ausführen mehrerer timed tests mit beiden Methoden, und dann Mittelwertbildung aus den Ergebnissen und vergleichen, oder können Sie erwägen, ein full-blown-profiling-tool, das fügt sich zu einem Prozess und Grafiken aus memory-Nutzung über die Zeit und die Ausführungsgeschwindigkeit.
Nicht stichprobenartig micro-code-tuning, weil Sie haben ein Bauchgefühl, es wird schneller. Compiler alle haben leicht unterschiedliche Implementierungen der Dinge und das, was wahr ist, auf einen compiler, der auf einer Umgebung falsch sein kann auf einer anderen Konfiguration.
Angehen, dass Kommentar über weniger Parameter: der Prozess der "inlining" von Funktionen im wesentlichen entfernt den overhead im Zusammenhang mit dem aufrufen einer Funktion. Chancen sind eine kleine Funktion werden automatisch in-gefüttert durch den compiler, aber Sie können schlage vor, eine Funktion inlined werden als gut.
In einer anderen Sprache C++, der neue standard coming-out unterstützt perfect forwarding und perfekte move-Semantik mit rvalue-Referenzen, die beseitigt die Notwendigkeit für Provisorien in bestimmten Fällen reduziert werden können die Kosten für den Aufruf einer Funktion.
Ich vermute, Sie sind vorzeitig optimieren, Sie sollten jedoch nicht, werden diese mit Leistung betrifft, bis Sie entdeckt haben, Ihre echte Engpässe.
Absolut nicht! Die einzige "Leistung" der Unterschied ist, wenn die Variablen initialisiert werden
Im ersten Fall die ganze Zahl auf 42 jedes mal, wenn die Funktion aufgerufen wird, im zweiten Fall in den ot gesetzt ist 42, wenn das Programm geladen wird.
Jedoch ist der Unterschied so trivial zu sein, kaum wahrnehmbar. Seine ein verbreiteter Irrtum, dass Speicher allokiert werden für die "automatische" Variablen bei jedem Aufruf. Das ist nicht so C verwendet, die schon reservierten Platz im stack für diese Variablen.
Statische Variablen tatsächlich langsam nach unten, als Ihre einige aggresive Optimierungen sind nicht möglich, auf statische Variablen. Auch wenn die Einwohner in einem zusammenhängenden Gebiet von dem Stapel sind Sie leichter zu cache effizient.
Gibt es keine Antwort auf diese Frage. Es hängt von der CPU, compiler, compiler-flags, die Anzahl der lokalen Variablen, die Sie haben, was die CPU macht, bevor Sie die Funktion aufrufen, und sehr wahrscheinlich der phase des Mondes.
Betrachten zwei extremen; wenn Sie nur eine oder ein paar lokale Variablen, es/Sie könnte leicht gespeichert werden in einem Register statt Speicher zugewiesen, Orte, an alle. Wenn register "Druck" ist hinreichend gering, dass dies passieren kann ohne ausführen von Anweisungen an alle.
Bei dem anderen extrem, es gibt ein paar Maschinen (z.B. IBM mainframes), die keine stacks bei allen. In diesem Fall, was würden wir normalerweise denken, der als stack-frames tatsächlich zugewiesen als verkettete Liste im heap. Wie würden Sie wahrscheinlich erraten, dies kann ganz langsam.
Wenn es um den Zugriff auf die Variablen, die situation ist etwas ähnliches-Zugriff auf eine Maschine registrieren ist ziemlich gut, garantiert schneller als alles, was zugeordnet im Speicher können mögliche Hoffnung für. OTOH, ist es möglich, für den Zugriff auf Variablen auf dem stack sehr langsam-es erfordert in der Regel so etwas wie ein indizierter Indirekter Zugang, was (vor allem bei älteren CPUs) dazu neigt, ziemlich langsam. OTOH, Zugang zu einem globalen (was eine statische ist, obwohl sein name nicht Global sichtbar) in der Regel erfordert, bilden eine absolute Adresse, die einige CPUs zu bestrafen, zu einem gewissen Grad als gut.
Bottom line: auch die Beratung Profil kann Ihr code verlegt werden -- der Unterschied kann leicht so winzig klein, dass auch ein profiler nicht erkennen, es zuverlässig, und die nur Weg, um sicher sein zu untersuchen, ist der Assembler erzeugt (und verbringen Sie ein paar Jahren Assembler zu lernen gut genug, um zu wissen, sagen nichts, wenn Sie tun es betrachtet). Die andere Seite ist, dass, wenn Sie ' re Umgang mit einem Unterschied kann man noch nicht mal Messen zuverlässig die Chancen, dass es wird haben einen wesentlichen Einfluss auf die Geschwindigkeit der echte code ist so abgelegen, dass es wahrscheinlich nicht der Mühe Wert.
Sieht es aus wie der statische vs. nicht-statische wurde komplett abgedeckt, aber auf das Thema der globalen Variablen. Oft werden diese immer langsamer Programme, die Ausführung eher als beschleunigen.
Der Grund ist, dass fest Gültigkeitsbereich von Variablen, die machen es einfach für den compiler stark optimieren, wenn der compiler sich über Ihre Bewerbung für Instanzen, wo ein global eingesetzt werden könnten, dann seine Optimierung sind nicht so gut.
Dieser wird verstärkt, wenn Sie die Einführung von Zeigern, sagen Sie den folgenden code:
weiß der compiler, dass die Zeiger A und B können nie überlappen und so kann es optimieren der Kopie. Wenn A und B sind global-dann könnten Sie möglicherweise zeigen Sie auf überlappende oder identische Speicher, dies bedeutet, dass der compiler muss "play it safe", die ist langsamer. Das problem ist in der Regel genannt werden 'pointer aliasing", und kann auftreten, in vielen Situationen, nicht nur den Speicher kopiert.
http://en.wikipedia.org/wiki/Pointer_alias
Ja, die Verwendung von statischen Variablen wird eine Funktion ein kleines bisschen schneller. Dies führt jedoch zu Problemen, wenn Sie jemals wollen, um Ihr Programm multi-threaded. Da statische Variablen werden freigegeben, zwischen Funktion aufrufen, aufrufen der Funktion gleichzeitig in verschiedenen threads führt zu undefiniertem Verhalten. Multi-threading ist die Art von Sache, die Sie möchten möglicherweise in der Zukunft zu tun, um wirklich beschleunigen Sie Ihren code.
Meisten Dinge, die Sie erwähnt werden, bezeichnet man als Mikro-Optimierungen. In der Regel, sich Gedanken über diese Art von Dingen ist ein schlechte Idee. Es macht den code schwerer lesbar und schwerer zu pflegen. Es ist auch sehr wahrscheinlich zu bugs einzuführen. Sie werden wahrscheinlich erhalten mehr bang für Ihre buck zu tun Optimierungen auf einer höheren Ebene.
Als M2tM Vorschläge, einen profiler laufen zu lassen ist auch eine gute Idee. Check-out gprof für eine die ist ganz einfach zu verwenden.
Können Sie immer die Zeit, Ihre Bewerbung um wirklich festzustellen, was ist am schnellsten. Hier ist, was ich verstehe: (all dies hängt von der Architektur des Prozessors, btw)
C-Funktionen erstellen Sie ein stack-frame, die ist, wo die Parameter übergeben werden, und lokale Variablen gesetzt werden, sowie der return-pointer zurück, wo der Anrufer die Funktion. Es gibt keine memory-management-Zuweisung hier. Es in der Regel eine einfache Zeiger-Bewegung und das Wars. Zugriff auf Daten aus dem Stapel ist auch ziemlich schnell. Strafen in der Regel ins Spiel kommen, wenn Sie den Umgang mit Zeigern.
Als für Globale oder statische Variablen, Sie sind die gleichen...von dem Standpunkt aus, dass Sie zugeordnet werden, in der gleichen region von Speicher. Der Zugriff auf diese kann eine andere Methode des Zugriffs als lokale Variablen, hängt von der compiler.
Den großen Unterschied zwischen den Szenarien ist, dass der Speicherbedarf nicht so viel Geschwindigkeit.
Verwendung von statischen Variablen können tatsächlich machen den code deutlich langsamer. Statische Variablen existieren müssen, die in einem 'data' Bereich des Speichers. Um zu verwenden, dass die variable, die die Funktion ausführen muss, eine load-Anweisung zu Lesen vom Hauptspeicher, oder einer store-Instruktion zu schreiben. Wenn das Gebiet ist nicht im cache, Sie verlieren viele Zyklen. Einer lokalen Variablen Leben auf dem stack werden die meisten sicherlich eine Adresse, die im cache gespeichert ist, vielleicht sogar in einem cpu-register, die nie erscheinen im Speicher.
Ich Stimme mit den anderen Kommentaren über profiling, um herauszufinden, solche Sachen, aber im Allgemeinen, eine Funktion statische Variablen sollte langsamer sein. Wenn Sie wollen, dass Sie, was Sie wirklich nach, ist eine Globale. Funktion Statik einfügen von code/Daten, um zu überprüfen, ob das Ding wurde schon initialisiert, die ausgeführt wird, jedes mal wenn Ihre Funktion genannt wird.
Profiling kann nicht den Unterschied sehen, Demontage und wissen, was zu suchen könnte.
Ich vermute, Sie sind nur gehen, um eine Schwankung, so viel wie ein paar clock-Zyklen pro Schleife (im Durchschnitt, je nach compiler, etc). Manchmal ist die Veränderung wird dramatische Verbesserung oder dramatisch langsamer, und das nicht unbedingt weil die Variablen nach Hause ging,/aus dem Stapel. Können sagen, Sie retten, vier clock-Zyklen pro Funktionsaufruf für 10000 Aufrufe auf einem 2-GHz-Prozessor. Sehr grobe Berechnung: 20 Mikrosekunden gespeichert. 20 Mikrosekunden viel oder wenig im Vergleich zu Ihrer aktuellen Ausführung Zeit?
Wird wahrscheinlich mehr eine performance-Verbesserung, indem Sie alle Ihre char-und short-Variablen in int-Werte, unter anderem. Mikro-Optimierung ist eine gute Sache zu wissen, aber es braucht viel Zeit, zu Experimentieren, zerlegen, Zeitpunkt der Ausführung des Codes, Verständnis, die weniger Anleitung bedeutet nicht unbedingt schneller zum Beispiel.
Nehmen Sie Ihr bestimmtes Programm, zerlegen die Funktion in Frage, und der code, der ihn aufruft. Mit und ohne das static. Wenn Sie gewinnen, nur ein oder zwei Anweisungen, und das ist die einzige Optimierung, die Sie tun werden, ist es wahrscheinlich nicht Wert. Sie sind möglicherweise nicht in der Lage, den Unterschied zu sehen, während des profilings. Änderungen, in dem die cache-lines Treffer angezeigt werden könnten bei der Profilerstellung, bevor Sie änderungen im code zum Beispiel.