Simplemente dé el tamaño exacto que necesita. La única razón por la cual un tamaño de potencia de dos podría ser "mejor" es permitir una asignación más rápida y/o evitar la fragmentación de la memoria.
Sin embargo, cualquier implementación no trivial de malloc
que se preocupe por ser eficiente redondeará internamente las asignaciones de esta forma siempre y cuando sea apropiado hacerlo. No necesita preocuparse por "ayudar" malloc; malloc puede hacerlo bien por sí mismo.
Editar:
En respuesta a su cotización del Joel sobre el artículo de software, punto de Joel en esa sección (que es difícil de discernir correctamente sin el contexto que sigue el párrafo que usted ha citado) es que si esperas con frecuencia re -asignar un buffer, es mejor hacerlo multiplicativamente, en lugar de hacerlo de manera aditiva. Esto es, de hecho, exactamente lo que hacen las clases std::string
y std::vector
en C++ (entre otros).
La razón de que esto es una mejora no es porque usted está ayudando a cabo malloc
proporcionando números convenientes, pero debido a la asignación de memoria es una operación costosa , y que está tratando de reducir al mínimo el número de veces que lo haces. Joel está presentando un ejemplo concreto de la idea de una compensación de tiempo-espacio. Argumenta que, en muchos casos en los que la cantidad de memoria necesaria cambia dinámicamente, es mejor perder algo de espacio (asignando hasta el doble de lo que necesita en cada expansión) para guardar tiempo que se requeriría para repetidamente vire exactamente n
bytes de memoria, cada vez que necesite n
más bytes.
El multiplicador no tiene que ser dos: puede asignar hasta tres veces más espacio que necesita y terminar con asignaciones en potencias de tres, o asignar hasta cincuenta y siete veces más espacio que usted necesita y termina con asignaciones en poderes de cincuenta y siete. Cuanta más asignación tenga, menos necesitará volver a asignar, pero perderá más memoria. Asignar en poderes de dos, que utiliza como mucho el doble de memoria que la necesaria, resulta ser una buena compensación de punto de partida hasta y a menos que tenga una mejor idea de cuáles son exactamente sus necesidades.
Menciona de paso que esto ayuda a reducir la "fragmentación en la cadena libre", pero la razón es más por el número y la uniformidad de las asignaciones que se realizan, que por su tamaño exacto. Por un lado, cuantas más veces asigne y desasigne memoria, más probabilidades tendrá de fragmentar el montón, sin importar el tamaño que esté asignando. En segundo lugar, si tiene varios búferes que está cambiando de tamaño dinámicamente utilizando el mismo algoritmo de cambio de tamaño multiplicativo, es probable que si uno cambia el tamaño de 32 a 64 y otro cambia de 16 a 32, la reasignación del segundo pueda caber justo donde el primero solía ser. Este no sería el caso si uno cambió el tamaño de 25 a 60 y el otro de 16 a 26.
Y de nuevo, nada de lo que él está hablando aplica si va a realizar el paso de asignación solo una vez .
No es mejor. Desperdicia la memoria. – Adrian
Supongo que en algunas plataformas, malloc() podría hacer asignaciones de tamaño de página con un tamaño mínimo de asignación.No he investigado mucho más, pero sé que muchas implementaciones de memoria personalizada lo hacen. – Simon