Ich weiß, dass es eine alte Frage ist, aber es gibt einige Dinge, die jeder zu vermissen scheint.
Erstens ist dies eine Multiplikation mit 2: Größe << 1. Dies ist eine Multiplikation mit etwas zwischen 1 und 2: int (Gleitkomma (Größe) * x), wobei x die Zahl ist, * Gleitkomma-Mathematik ist und der Prozessor hat um zusätzliche Anweisungen zum Gießen zwischen float und int auszuführen. Mit anderen Worten, auf Maschinenebene erfordert das Verdoppeln eine einzige, sehr schnelle Anweisung, um die neue Größe zu finden. Das Multiplizieren mit etwas zwischen 1 und 2 erfordert mindestenseine Anweisung zum Umwandeln der Größe in einen Float, eine Anweisung zum Multiplizieren (was eine Float-Multiplikation ist, sodass es wahrscheinlich mindestens doppelt so viele Zyklen dauert, wenn nicht vier- oder sogar achtmal so viele) und eine Anweisung zum Zurückwandeln in int. Dies setzt voraus, dass Ihre Plattform Float-Mathematik für die Allzweckregister durchführen kann, anstatt die Verwendung spezieller Register zu erfordern. Kurz gesagt, Sie sollten erwarten, dass die Mathematik für jede Zuordnung mindestens zehnmal so lange dauert wie eine einfache Linksverschiebung. Wenn Sie jedoch während der Neuzuweisung viele Daten kopieren, macht dies möglicherweise keinen großen Unterschied.
Zweitens und wahrscheinlich der große Kicker: Jeder scheint anzunehmen, dass der Speicher, der freigegeben wird, sowohl an sich selbst als auch an den neu zugewiesenen Speicher angrenzt. Dies ist mit ziemlicher Sicherheit nicht der Fall, es sei denn, Sie weisen den gesamten Speicher selbst vorab zu und verwenden ihn dann als Pool. Das Betriebssystem kann gelegentlichAm Ende tun Sie dies, aber die meiste Zeit wird es genug Fragmentierung des freien Speicherplatzes geben, damit jedes halbwegs anständige Speicherverwaltungssystem ein kleines Loch finden kann, in das Ihr Speicher gerade passt. Sobald Sie wirklich kleine Stücke bekommen, werden Sie mit größerer Wahrscheinlichkeit zusammenhängende Teile erhalten, aber bis dahin sind Ihre Zuweisungen groß genug, dass Sie sie nicht häufig genug ausführen, damit es nicht mehr darauf ankommt. Kurz gesagt, es macht Spaß, sich vorzustellen, dass die Verwendung einer idealen Zahl die effizienteste Nutzung des freien Speicherplatzes ermöglicht. In Wirklichkeit wird dies jedoch nur geschehen, wenn Ihr Programm auf Bare Metal ausgeführt wird (wie in, es gibt kein Betriebssystem) darunter alle Entscheidungen treffen).
Meine Antwort auf die Frage? Nein, es gibt keine ideale Zahl. Es ist so anwendungsspezifisch, dass es niemand wirklich versucht. Wenn Ihr Ziel die ideale Speichernutzung ist, haben Sie ziemlich viel Pech. Für die Leistung sind weniger häufige Zuweisungen besser, aber wenn wir nur so weitermachen, könnten wir mit 4 oder sogar 8 multiplizieren! Wenn Firefox auf einmal von 1 GB auf 8 GB springt, werden sich die Leute beschweren, so dass dies nicht einmal Sinn macht. Hier sind einige Faustregeln, nach denen ich mich richten würde:
Wenn Sie die Speichernutzung nicht optimieren können, verschwenden Sie zumindest keine Prozessorzyklen. Das Multiplizieren mit 2 ist mindestens eine Größenordnung schneller als das Gleitkomma-Rechnen. Es mag keinen großen Unterschied machen, aber es wird zumindest einen Unterschied machen (besonders früh, während der häufigeren und kleineren Zuteilungen).
Überdenken Sie es nicht. Wenn Sie nur 4 Stunden damit verbracht haben, herauszufinden, wie Sie etwas tun können, was bereits getan wurde, haben Sie nur Ihre Zeit verschwendet. Ganz ehrlich, wenn es eine bessere Option als * 2 gegeben hätte, wäre dies vor Jahrzehnten in der C ++ - Vektorklasse (und an vielen anderen Orten) geschehen.
Wenn Sie wirklich optimieren möchten, sollten Sie die kleinen Dinge nicht ins Schwitzen bringen. Heutzutage kümmert sich niemand mehr darum, dass 4 KB Speicher verschwendet werden, es sei denn, sie arbeiten an eingebetteten Systemen. Wenn Sie 1 GB Objekte zwischen 1 MB und 10 MB erreichen, ist das Verdoppeln wahrscheinlich viel zu viel (ich meine, das sind zwischen 100 und 1.000 Objekte). Wenn Sie die erwartete Expansionsrate schätzen können, können Sie sie an einem bestimmten Punkt auf eine lineare Wachstumsrate ausgleichen. Wenn Sie ungefähr 10 Objekte pro Minute erwarten, ist es wahrscheinlich in Ordnung, mit 5 bis 10 Objektgrößen pro Schritt (einmal alle 30 Sekunden bis zu einer Minute) zu wachsen.
Es kommt darauf an, nicht zu überlegen, zu optimieren, was Sie können, und bei Bedarf an Ihre Anwendung (und Plattform) anzupassen.