2012-11-09 14 views
9

Wenn ich dies tun: -Do std :: function und std :: bind tun dynamische Speicherzuweisung?

class Thing 
{ 
    ... 
    void function (const std::string& message); 
}; 

std::list<std::function<void()>> work; 

und in einigen Mitglied der "Sache"

work.push_back(std::bind(&Thing::function, this, "Hello")); 

Hat entweder der Aufruf von std :: binden oder die Verwendung von std :: function <> Ursache jede dynamische Speicherzuweisung mit neuen oder anderen? Oder wird der gesamte Speicher zur Kompilierzeit zugewiesen? Wenn der Standard nichts sagt, wie sieht es in Visual Studio 2012 aus, da mein Programm nur darauf aufbauen muss, und aus Effizienzgründen muss ich wahrscheinlich dynamische Speicherzuweisungen an der Stelle vermeiden, an der ich diesen Mechanismus verwenden möchte.

+6

„für Effizienz ich wahrscheinlich“ Sie sollten keine Annahmen über die Effizienz so machen. – slaphappy

+5

Die Verwendung von 'std :: list' verursacht bei jedem Hinzufügen eines Elements zur Liste eine Speicherzuweisung. –

+1

Ahahahahahaha Vermeidung dynamischer Zuordnungen während der Verwendung von Std :: list –

Antwort

14

Der Standard ist nicht festgelegt, aber es ist leicht zu sehen, dass im Allgemeinen std::function Speicher zumindest in einigen Fällen zuteilen müssen:

struct huge { char c[10000]; }; 
void foo(const huge &); 
std::function<void()>{std::bind(foo, huge{})}; 

Auf der anderen Seite möglich, es ist für sich Zuordnung zu vermeiden, in mindestens einige Fälle, indem das Funktionsobjekt in einem vorab zugewiesenen Puffer innerhalb des Objekt-Footprints platziert wird; Offensichtlich gibt es einen Kompromiss, da andere Anwendungen mehr Stapelspeicher benötigen. Eine gute Implementierung wäre in der Lage, eine Speicherzuweisung zu vermeiden, wenn ein Raw-Funktionszeiger in einem function Objekt gespeichert wird, und möglicherweise auch für einen mem_fn, aber es ist weniger wahrscheinlich, dass dies für eine bind geschieht. B. libstdC++ (g ++) Inlinefunktionszeiger (functor), Funktionszeiger und (nichtvirtuelle) Mitgliedsfunktionszeiger sowie alles andere, das in dieselbe Grundfläche passen würde, z. Staatenlose Funktoren (union _Nocopy_types).

Wenn Sie können, indem Sie Ihren Steuerfluss Umkehren Objekte Templat-Funktors zu akzeptieren statt function Sie zusätzliche Speicherzuweisung vermeiden:

template<typename F> 
void my_algorithm(const F &); 
my_algorithm(std::bind(foo, huge{})); 
+0

Ok, das macht Sinn, danke – jcoder

0

ich darüber bin nicht sicher. Ich denke, wie es ecatmur nahelegt, hängt es von der Implementierung von std für diese Plattform ab. Bei ähnlichen Problemen hatte ich mit dieser Implementierung aus dem Code-Projekt gute Erfolge. Es unterstützt eine gute Anzahl von Plattformen. Sehr gut dokumentiert und keine dynamische Speicherzuweisung.

http://www.codeproject.com/Articles/7150/Member-Function-Pointers-and-the-Fastest-Possible

General purpose dynamische Speicherzuweisung zur Laufzeit in den Spielen oder Simulation soll vermieden werden. Das Problem ist nicht immer Fragmentierung oder ein großer Engpass (beide gültige Gründe zu vermeiden), sondern auch die Tatsache, dass die Menge an Zeit oft nicht deterministisch ist. Eine eher domänenspezifische Speicherzuteilungsstrategie wie "Pooling" oder "Framing" wäre hier von Vorteil.

http://g.oswego.edu/dl/html/malloc.html

Verwandte Themen