3 Stimmen

Wie auf Stack vs Heap vs Boost::Pool Zuordnung in einem Fall wie diesem zu entscheiden?

Ich habe eine Klasse, die boost::variant verwendet, um ein Double oder eine Zeichenfolge zu speichern, wie diese:

class value
{
  boost::variant<double, std::string> val;
};

Es soll ein unveränderlicher Werttyp für einen Spielzeug-Interpreter sein, mit dem ich spiele. Zuerst schien es eine gute Idee zu sein, ihn per Const-Referenz zu übergeben und per Value zurückzugeben, und ihn immer auf dem Stack zu allozieren, da ich ihn als Primitiv behandeln wollte. Dann sah ich jedoch, dass seine Größe 40 Bytes beträgt (hauptsächlich aufgrund von sizeof std::string), und ich war etwas besorgt. Ich weiß, ich sollte nicht große Stücke von Speicher auf Stack zuweisen, aber wie groß ist zu groß?

Außerdem scheint das Kopieren von 40 Bytes jedes Mal, wenn ich zurückkehre, vor allem, da der Wert unveränderlich ist und nicht einmal kopiert werden muss, eine ziemliche Verschwendung zu sein.

Die Option reguläre Heap-Zuweisung scheint nicht sehr attraktiv, da ich Tausende dieser Zuweisungen/Deallokationen pro Sekunde haben könnte.

Die letzte Option, die mir eingefallen ist, ist ein boost::pool, um diese Objekte bei Bedarf zuzuweisen, und ein boost::shared_ptr, um ihre Lebensdauer zu verwalten. Da jedoch der Interpreter für die Speicherzuweisung zuständig ist (die Art der Speicherzuweisung wird eine Richtlinie sein, die dem Interpreter als Template-Argument übergeben wird), würde dies bedeuten, dass die Value-Klasse über den Interpreter Bescheid wissen müsste, was die Dinge etwas verkompliziert.

Dies sind also die Fragen:

  • Was sollte ich in diesem Fall tun und warum?
  • Wie groß ist "zu groß" für die Zuweisung auf dem Stack? Ich bin sicher, das hängt davon ab, wie oft er zugewiesen wird und wie oft er kopiert werden muss.

Gracias.

4voto

sbi Punkte 211669
  • Was sollte ich in diesem Fall tun und warum?

Wie immer sollten Sie das Programm so schreiben, dass es möglichst einfach zu verstehen ist. Wenn Profiling später feststellt, dass dies tatsächlich ein Problem ist, können Sie jederzeit value::val später in ein dynamisch zugewiesenes Objekt umzuwandeln. (Dies setzt natürlich voraus, dass val so weit abstrahiert werden, dass dies keine Auswirkungen auf die Clients der Klasse hat).

  • Wie groß ist "zu groß" für die Zuweisung auf dem Stack? Ich bin sicher, das hängt davon ab, wie oft es zugewiesen wird und wie oft es kopiert werden muss.

Es hängt auch davon ab, auf welcher Plattform Sie sich befinden. Reden wir über den 8-Bit-Embedded-Chip, auf dem Ihr Toaster läuft, oder über eine 64-Bit-Workstation?
IMO läuft es letztendlich auf Folgendes hinaus: Es ist zu groß, wenn es aufgrund seiner Größe Probleme verursacht.

0voto

Matthieu M. Punkte 266317

Wenn Sie dies wirklich optimieren müssen, würde ich empfehlen, keine std::string unter Windows.

Für unveränderliche Zeichenketten könnte eine Copy-on-Write-ähnliche Implementierung (im Grunde teilen sich alle Kopien der Zeichenkette denselben internen Puffer) leicht auf der Grundlage von shared_ptr .

Da Sie dann nur noch einen einzigen Zeiger in Ihrer ConstString Klasse müssen Sie sich nicht um die Übergabe durch Kopie kümmern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X