2017-08-04 4 views
0

J'utilisé unordered_multiset dans mon code par les deux raisons suivantes,Comment réduire la consommation de mémoire de unordered_multiset?

  1. devrait être facile à trouver ou consulter les données.
  2. Devrait prendre en charge pour charger les valeurs en double.

unordered_multiset sont généralement beaucoup plus rapide que multijeux & vecteur, à la fois pour l'insertion et pour la recherche, et parfois même pour la suppression.

Mais la mauvaise chose est, il prend trop de mémoire.

J'ai stocké des valeurs non signées __int64 (8 octets) dans unordered_multiset et efface correctement les valeurs de unordered_multiset. pouvez-vous expliquer quelqu'un, pourquoi il prend la mémoire & comment résoudre cette consommation de mémoire?

+4

Comment avez-vous mesuré la consommation de mémoire? – Drek

+0

@Drek j'ai obtenu les détails de consommation de mémoire à partir du Gestionnaire des tâches. Je le trouve en utilisant l'identifiant de processus de mon application. – Durai

+2

Combien d'éléments * distincts * insérez-vous? Quelle est la taille de l'empreinte mémoire de votre 'unordered_multiset' une fois que toutes les valeurs ont été insérées? – dasblinkenlight

Répondre

0

Vous pouvez obtenir une bien meilleure mesure de l'espace utilisé par un conteneur std:: en lui attribuant un allocateur personnalisé qui consigne le montant qu'il est demandé d'allouer.

par exemple.

std::size_t total_allocation = 0; 

template< class T > 
struct logging_allocator 
{ 
    using value_type = T; 
    using pointer = T*; 
    using const_pointer = const T*; 
    using reference = T&; 
    using const_reference = const T&; 
    using size_type = std::size_t; 
    using difference_type = std::ptrdiff_t; 
    using propagate_on_container_move_assignment = std::true_type; 
    template< class U > struct rebind { using other = logging_allocator<U>; }; 
    using is_always_equal = std::true_type; 

    pointer address(reference x) const { return base.address(x); } 
    const_pointer address(const_reference x) const{ return base.address(x); } 

    pointer allocate(size_type n, const_pointer hint = nullptr){ 
     total_allocation += n; 
     return base.allocate(n, hint); 
    } 
    pointer allocate(size_type n, const void * hint){ 
     total_allocation += n; 
     return base.allocate(n, hint); 
    } 
    pointer allocate(size_type n){ 
     total_allocation += n; 
     return base.allocate(n, hint); 
    } 

    void deallocate(T* p, size_type n) { 
     total_allocation -= n; 
     return base.deallocate(p, n); 
    } 

    size_type max_size() const { 
     return base.max_size(); 
    } 

    void construct(pointer p, const_reference val) { 
     total_allocation += sizeof(T); 
     return base.construct(p, val); 
    } 
    template< class U, class... Args > 
    void construct(U* p, Args&&... args) { 
     total_allocation += sizeof(U); 
     return base.construct(p, args...); 
    } 

    void destroy(pointer p) { 
     total_allocation -= sizeof(T); 
     return base.destroy(p); 
    } 
    template< class U > 
    void destroy(U* p) { 
     total_allocation -= sizeof(U); 
     return base.destroy(p); 
    } 

private: 
    std::allocator<T> base; 
} 
0

Caleth a une bonne suggestion, sinon, vous pouvez regarder memory usage within processes

juste avant que vous insérez dans le multiset et après.

Très probablement cours de la différence, une énorme DLL est chargée.