2011-09-08 41 views
6

Tengo una pregunta sobre el rendimiento de std :: vector <> en C++. ¿Es más rápido reutilizar el mismo vector llamando a su método clear() o más rápido para recrear el vector?¿qué es más rápido: recrear o borrar()?

El siguiente ejemplo es ningún código de la vida real, es sólo por dejando claro lo que la pregunta es:

//Example ONE: is this faster 
std::vector<int> foo; 
for(int i = 0; i < 100; ++i) 
{ 
    foo.clear(); 
    for(int j = 0; j < 100; ++j) 
    { 
     foo.push_back(i+j); 
    } 
} 

//Example TWO: or is that faster? 
for(int i = 0; i < 100; ++i) 
{ 
    std::vector<int> foo; 
    for(int j = 0; j < 100; ++j) 
    { 
     foo.push_back(i+j); 
    } 
} 
+0

¿No son esas cosas la implementación dependiente? –

+6

Perfílmelo. ¡Boooooring! –

+3

¿Por qué todos los votos a favor? – Daniel

Respuesta

7

El clear() no puede por su contrato de desasignar la memoria vector, en lugar de simplemente establece el "tamaño" indicador interno a 0, por lo que ese método será más rápido.

+1

Más que "levemente", diría. –

+1

No conozco ninguna implementación que libere la memoria. –

+0

@David: ¡Crear un nuevo vector sí lo hace! : D [editar: sí, vale, dejar que el antiguo muera] –

0

El ejemplo 2 tiene asignaciones de pila repetidas para la matriz dentro de std :: vector. El ejemplo 1 es más rápido porque evita la asignación repetida de memoria en el montón, a menos que el vector deba redimensionarse internamente.

+0

's/asignación de memoria en la memoria de asignación dinámica/montón /' –

0

Tendrá que ejecutar puntos de referencia para su compilador. Los métodos clear() y 'allocate' dependen de la implementación.

+0

Que la capacidad de un vector nunca se reduce no depende de la implementación en absoluto. [edit: aunque C++ 11 _does_ tiene 'shrink_to_fit'] –

+0

@Tomalak: en realidad estaba pensando en ello. No hay una cláusula específica en el estándar que impida que la implementación realmente libere la memoria. Un vector que * se contrae * sería más difícil de implementar en muchos casos (mientras se mantiene el * costo constante amortizado * de 'push_back'), pero no creo que sea * imposible *, y eso para el caso general de 'erase', con los detalles de' clear() 'No veo ningún motivo por el que una implementación conforme no pueda liberar la memoria (de nuevo, no he ido más allá del estándar buscando este caso en particular ...) –

+0

@David: he estado revisándolo también. No veo ninguna garantía de que 'clear' * must * invoque' reserve'. Parece bastante implícita para mí, pero no está indicado. –

2

Depende de la implementación de std::vector en la biblioteca estándar de C++ que está utilizando, pero es probable que el primer caso sea más rápido porque la mayoría de las implementaciones no asignan memoria asignada cuando llama al std::vector::clear. Entonces, el primero no realiza asignaciones repetidas una vez que el bucle interno se ha ejecutado la primera vez.

0

Para ambos borrar un vector y reducir su capacidad al mínimo de su aplicación, Scott Meyers recomienda el truco de intercambio:

std::vector<int>().swap(foo); 

Sería también ser más rápido que la iteración a través del vector con un lazo enrollado a mano a restaurar sus contenidos

1

Sí. No. El primero es más rápido, probablemente. Depende. La única respuesta útil proviene de que perfile su propio código en su propio entorno.

Probar el perfil de su código para ver qué pasa. Compilar your program at ideone revela que, para un compilador particular/os/machine/run, su primer ejemplo es 4 veces más rápido.

Y this program muestra una solución intermedia, que va más rápido que # 2, más lento que el # 1, para este compilador particular/os/machine/run.

0

En este caso específico, la caja de reutilización probablemente sea más rápida en la mayoría de las máquinas. Está almacenando datos primitivos que no necesitan destrucción (o incluso tienen un destructor). Por otro lado, si el vector contiene objetos que no son POD, cada elemento será destruido por la llamada al clear. Por otro lado, todos los datos acumulados deberán ser destruidos eventualmente.

Cuestiones relacionadas