Sé que es una vieja pregunta, pero hay varias cosas que a todos parece faltar.
En primer lugar, esto es la multiplicación por 2: tamaño < < 1. Esta es la multiplicación por nada entre 1 y 2: int (float (tamaño) * x), donde x es el número, el punto * está flotando matemática, y el procesador debe ejecutar instrucciones adicionales para transmitir entre float e int. En otras palabras, a nivel de máquina, duplicar requiere una sola instrucción muy rápida para encontrar el nuevo tamaño. Multiplicar por algo entre 1 y 2 requiere al menos una instrucción para lanzar tamaño a un flotador, una instrucción para multiplicar (que es multiplicación flotante, por lo que probablemente lleve al menos el doble de ciclos, si no 4 o incluso 8 veces más muchos) y una instrucción para volver a int, y eso supone que su plataforma puede realizar operaciones de flotación en los registros de propósito general, en lugar de requerir el uso de registros especiales. En resumen, debe esperar que los cálculos para cada asignación tarden al menos 10 veces más que un simple desplazamiento a la izquierda.Sin embargo, si está copiando una gran cantidad de datos durante la reasignación, esto podría no representar una gran diferencia.
En segundo lugar, y probablemente sea el gran pateador: todo el mundo parece suponer que la memoria que se está liberando es a la vez contigua consigo misma y contigua a la memoria recién asignada. A menos que esté preasignando toda la memoria usted mismo y luego la use como grupo, este no es el caso. El OS puede ocasionalmente terminar haciendo esto, pero la mayoría de las veces, habrá suficiente fragmentación del espacio libre que cualquier sistema de gestión de memoria medio decente podrá encontrar un pequeño agujero donde su memoria se ajuste. Una vez que llegue a trozos realmente pequeños, es más probable que termine con piezas contiguas, pero para entonces, sus asignaciones son lo suficientemente grandes como para que no las haga con la frecuencia suficiente como para que ya no importen. En resumen, es divertido imaginar que usar un número ideal permitirá el uso más eficiente del espacio de memoria libre, pero en realidad, no va a suceder a menos que su programa se esté ejecutando en metal desnudo (como en, no hay sistema operativo). debajo toma todas las decisiones).
Mi respuesta a la pregunta? No, no hay un número ideal. Es tan específico de la aplicación que nadie realmente lo intenta. Si su objetivo es el uso ideal de la memoria, no tiene suerte. Para el rendimiento, las asignaciones menos frecuentes son mejores, pero si nos limitamos a eso, ¡podríamos multiplicar por 4 o incluso 8! Por supuesto, cuando Firefox salta de usar 1GB a 8GB de una sola vez, la gente se va a quejar, por lo que ni siquiera tiene sentido. Aquí hay algunas reglas generales que iría sin embargo:
Si no puede optimizar el uso de la memoria, al menos no pierda los ciclos del procesador. Multiplicar por 2 es al menos un orden de magnitud más rápido que hacer matemática de punto flotante. Puede que no haga una gran diferencia, pero al menos hará una diferencia (especialmente al principio, durante las asignaciones más frecuentes y más pequeñas).
No lo piense demasiado. Si solo pasas 4 horas tratando de descubrir cómo hacer algo que ya se ha hecho, simplemente perdiste el tiempo. Honestamente, si hubiera una opción mejor que * 2, se habría hecho en la clase de vectores C++ (y en muchos otros lugares) hace décadas.
Por último, si realmente desea optimizar, no se preocupe por las cosas pequeñas. Hoy en día, a nadie le importa perder 4 KB de memoria, a menos que trabajen en sistemas integrados. Cuando llega a 1 GB de objetos que están entre 1 MB y 10 MB cada uno, duplicar es probablemente demasiado (es decir, eso es entre 100 y 1.000 objetos). Si puede estimar la tasa de expansión esperada, puede nivelarla a una tasa de crecimiento lineal en un cierto punto. Si espera alrededor de 10 objetos por minuto, entonces crecer de 5 a 10 tamaños de objeto por paso (una vez cada 30 segundos a un minuto) probablemente sea suficiente.
Todo se reduce a, no lo piense demasiado, optimice lo que pueda y personalice su aplicación (y plataforma) si es necesario.
Para más información, duplicar el tamaño de la matriz significa que obtiene ** insertos ** O (1) amotizados. La idea es que cada vez que insertas un elemento, también copias un elemento de la matriz anterior. Digamos que tiene una matriz de tamaño _m_, con _m_ elementos en ella. Al agregar el elemento _m + 1_, no hay espacio, por lo que asigna una nueva matriz de tamaño _2m_. En lugar de copiar todos los primeros elementos _m_, copie uno cada vez que inserta un nuevo elemento. Esto minimiza la varianza (excepto para la asignación de la memoria), y una vez que haya insertado elementos de 2 m, habrá copiado todos los elementos de la matriz anterior. – hvidgaard