performance von new
-
Optimizer schrieb:
int hat schon Konstruktoren, einen default-Konstruktor und einen copy-Konstruktor. Der wird aber von new[] nicht aufgerufen.
MSDN schrieb:
When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/express_25.asp
The new operator accepts the name of a class (remembering that in C++ everything (int, long, double, class,...) is considered to be a class) and returns either (1) a pointer to the allocated piece of memory or (2) a 0 (if the allocation failed).
http://www.grc.nasa.gov/WWW/price000/pfc/htm/cpp_new.html
BTW: int hat auch andere Konstruktoren.
int a('0'); int b(5.6); // mit einer warnung, versteht sich
-
ok danke fuer die antworten.
Wenn ich euch jetz richtig verstanden habe dann braucht der operator new[](wenn man konstruktoren ausser acht laesst) constante zeit. aber dauert es nicht wesentlich laenger ein grosses, zusammenhaengendes stueck arbeitsspeicher zu finden (arbeitsspeicher stark fragmentiert zb)?und noch eine frage zum thema: dauert dann auch ein
new int;genau so lange wie ein
new int[GROSSE_ZAHL];diese fragen hoeren sich vielleicht doof an aber da ich absolut keine ahnung hab wie diese operatoren implementiert sind in windows, koennte ich mir auch durchaus vorstellen das der aufruf von new(der ja relativ teuer ist) die meiste zeit mit etwas verbringt das mit der groesse des angeforderten speicherplatzes nur wenig zu tun hat.
-
a&l schrieb:
ok danke fuer die antworten.
Wenn ich euch jetz richtig verstanden habe dann braucht der operator new[](wenn man konstruktoren ausser acht laesst) constante zeit. aber dauert es nicht wesentlich laenger ein grosses, zusammenhaengendes stueck arbeitsspeicher zu finden (arbeitsspeicher stark fragmentiert zb)?Ein einfaches Test-Beispiel würde dir ziemlich schnell beweisen das dies
nicht so ist. Wenn, aufgrund einer "grossen" Speicheranforderung, die
Speicherverwaltung anfängt nach Platz zu suchen dann merkst das ganz sicher.
Unter Windows hört man das sogar deutlich, wenn sie nämlich anfängt auf Platte
auszulagern.Das hat jedoch nichts mit new zu tun sondern mit der Speicherverwaltung im
allgemeinen.
-
Apollon schrieb:
BTW: int hat auch andere Konstruktoren.
int a('0'); int b(5.6); // mit einer warnung, versteht sichDas ist Schmarrn. Da findet eine implizite Konvertierung statt. Und int ist ein Built-In und kein Klassentyp, der hat keine Konstruktoren im C++-Sinne.
-
otze schrieb:
Btw: new[] ist darauf optimiert, große Datenmengen gleichzeitig zu holen.
dann ist dein compiler kaputt. probier man einen von microsoft aus.
malloc sollte optimiert sein für große speicherblöcke, new sollte optimiert sein für kleine speicherblöcke. das ergibt sich unmittelbar daraus, wie man in den beiden sprachen programmiert und hat auch was mit virtuellen funktionen zu tun.
-
volkard schrieb:
otze schrieb:
Btw: new[] ist darauf optimiert, große Datenmengen gleichzeitig zu holen.
dann ist dein compiler kaputt. probier man einen von microsoft aus.
malloc sollte optimiert sein für große speicherblöcke, new sollte optimiert sein für kleine speicherblöcke. das ergibt sich unmittelbar daraus, wie man in den beiden sprachen programmiert und hat auch was mit virtuellen funktionen zu tun.
war nicht das größte problem von new und new[], dass man einen unheimlichen performance und speicher overhead hat, wenn man viele kleine Objekte erstellt?(hab da mal was von 10-50% gehört)
-
Für den normalen Gebrauch ist new ausreichend, aber auf Plattformen mit geringem Speichervorrat oder wenn man echt mit dem Messer zwischen den Zähnen durch die Gegend rauscht sollte trotzdem ein Small-Objekt Allokator verwendet werden. Damit kann man sich einigen Overhead sparen.
-
@a&l
diese fragen hoeren sich vielleicht doof an aber da ich absolut keine ahnung hab wie diese operatoren implementiert sind in windows,
Im Gegenteil, Du machst Dir aus Sicht der Performance zumindest an der richtigen Stelle die Gedanken ...
Und grad dieses Thema traegt wahnsinnig zu dem "schlechten" Ruf bei, den C++ in Sachen Performance hat, gegenüber C ... und das unbegruendet.
Nich umsonst liest man oefters die (meiner Meinung nach idiotische) Meinung, das fuer spiele C++ zu langsam ist und man zumindest die Engines in C programmieren sollte ...Also was zum merken.
- Dynamisch speicher anfordern iss teuer.
- nen new und nen malloc nehmen sich nicht viel !!! Teste es aus, du wirst kaum unterschiede merken ...
- deine new / malloc Kosten sind abhaengig vom BS, Systemzustand, HW etc ...
- einmal 200 MB oder 2 x 100 MB anfordern, iss abhangig vom BS und systemzustand, was schneller ist, da wirst um nen profiler Lauf nich herumkommen
- 1 MB im stueck oder 1000x 1kb anfordern, da wird die 1MB variante immer schneller sein .... deshalb ist der Generelle Umgang mit Speicher im C-Style meist performanter als der im C++ Style (wenn man nich aufpasst). Aber C++ bietet auch mittel und Moeglichkeiten, Speicher im Block zu allokieren und trotzdem sauber C++ zu schreiben.Fazit:
- Nimm wo du kannst den Stack ...
- wenn du dynamsich allokieren musst, (meist Listen unbekannter groesse) nutze Allokatoren, z.B. die von der STL, die sind immer performanter (wenn man sie richtig einsetzt) als allokieren mit blossem new
- Lerne zu denken und zu handeln wie C-Programmierer es von der pike auf lernen. Also z.B. zu entscheiden ob viel Speicher auf verdacht zu allokieren besser fuer dein prog ist, als weniger speicher zu beanspruchen, dafuer aber oefters mals erweitern und damit "teuer" ofters den Speichermanager zu befragen und daten zu verschieben.
- versuche sowas in laufzeitunkritische bereiche zu verlegen ....Ciao ...
-
otze schrieb:
war nicht das größte problem von new und new[], dass man einen unheimlichen performance und speicher overhead hat, wenn man viele kleine Objekte erstellt?(hab da mal was von 10-50% gehört)
new ist teuer. freispeicher allgemein. viel teurer als der stack.
um mal ein extrembeispiel zu machen: einmal new int[1000000] kostet für das besorgen des speichers ein paar takte, wenn wir glück haben nur 100 stück. aber 1000000 mal new int[1] kostet schonmal eine million funktionsaufrufe, was auf jeden fall mehr ist.
also meidet man kleine allokierungen gerne. aber man sollte auch ein auge drauf haben, wo man rummeidet. bei virtuellen funktionen und freispeicher und listen voller basisklassenzeigern (übliche geschichte das) handelt man sich schnell ärger ein, wenn man den code nicht einfach läßt. und der globale new sollte eh nen small-object-allocator schon drin haben. also fürchterbar sparen kann man nicht ohne zaubern (ok, faktor 70, wenn man mogelt und den speicher einfach nicht ans bs zurückgibt, sondern in seiner freispeicherliste hält und die anwendung single-threaded ist, aber das giltet nicht.).
-
1. hat T einen nicht trivialen konstruktor spielt es für grosse N keine rolle ob du nun einmal new T[NN] oder N mal new T[N] durchführst. die zeit, die zum reservieren des speichers benötigt wird, ist dann auf jeden fall klein gegenüber der zeit, die zum initialisieren benötigt wird.
2. für alle operatoren new[] die man praktisch verwenden wird, gibt es eine maximale ausführungszeit (wartezeit auf irgendwelche mutexes etc. mal ausgenommen) für alle N. folglich wird für grosse M ein new T[NM] (amortisiert) N mal so schnell sein wie N mal new T[M] wenn T ein POD ist (oder einen trivialen konstruktor hat).
3. stackspeicher ist begrenzt. die ausführungszeit zum reservieren ist hier faktisch konstant und wartefrei und schneller als jedes new.
4. allokatoren können den speicher- und ausführungsoverhead von new[] minimieren (letzlich sind sie ja je nach implementation auch nur eine variante von erst-mal-viel-reservieren-und-dann-selber-zuteilen), allerdings ist der overhead von new[] führt grosse arrays weitgehend vernachlässigbar, allokatoren werden interessant wenn man viele einzelne objekte hat.