2011-11-25 10 views
6

Tengo una pregunta para la que no soy capaz de encontrar la respuesta en la red ...¿Por qué la desasignación es lenta?

Tengo un conjunto declarado como esto:

set<unsigned int> MySet 

Estoy insertando un millón de números aleatorios generados con Mersenne Twister . La generación aleatoria y la inserción son realmente rápidas (alrededor de un segundo para un millón de números), pero la desasignación es extremadamente lenta (1 minuto y medio).

¿Por qué la desasignación es tan lenta? No estoy usando ningún destructores personalizados para el conjunto.

+0

No sé qué sistema operativo está utilizando, pero podría ser que la memoria se vuelva a compactar después de liberar cada fragmento. –

+2

¿Ha compilado con las optimizaciones activadas? -O3 –

+0

Windows 7x64. Compilando en Visual Studio 2010. ¿Hay alguna manera de acelerar la desasignación? –

Respuesta

7

Compila tu código en modo de lanzamiento.

Esto hace dos cosas.

  1. Enciende las optimizaciones que definitivamente ayudan.
  2. También las bibliotecas de administración de memoria son diferentes para depurar y liberar.
    La versión de depuración de la biblioteca está diseñada para permitir la depuración y mantienen información adicional (como marcar la memoria no asignada). Todo este procesamiento adicional cuesta
    • El objetivo de las dos versiones de la biblioteca es completamente diferente. La versión de lanzamiento está definitivamente optimizada para la velocidad en que la versión de depuración está optimizada para recuperación y depuración.

Nota esta información es de aproximadamente DevStudio.

1

Probablemente porque tiene más sentido optimizar la asignación a expensas de la desasignación, porque muchas aplicaciones asignan sin desasignar, pero nunca viceversa. He visto un patrón similar yo mismo, en una aplicación que mezcla llamadas a malloc y free (en lugar de asignar y desasignar todas a la vez).

Nunca he escrito un asignador de montón, así que no sé si hay una razón técnica más profunda que eso. Al desasignar, los bloques libres adyacentes deben encontrarse y fusionarse. Entonces el trabajo es fundamentalmente diferente.

90 segundos para 1 millón de free() suena bastante lento. Nunca he programado Windows, así que no puedo decir si eso es anormal, pero el sistema debería ser capaz de hacerlo mucho mejor.

La solución a su problema puede ser simplemente omitir la liberación de los objetos antes de que el programa finalice. Puede intentar derivar un asignador personalizado del std::allocator< unsigned int >, que hace que deallocate no sea operativo.

Cuestiones relacionadas