[Bf-blender-cvs] [34fda46a3eb] functions: produce lookup statistics for map and set
Jacques Lucke
noreply at git.blender.org
Fri Apr 19 11:22:00 CEST 2019
Commit: 34fda46a3eb446636146d9f4d5db593a20ef4800
Author: Jacques Lucke
Date: Fri Apr 19 11:19:23 2019 +0200
Branches: functions
https://developer.blender.org/rB34fda46a3eb446636146d9f4d5db593a20ef4800
produce lookup statistics for map and set
===================================================================
M source/blender/blenlib/BLI_array_lookup.hpp
M source/blender/blenlib/BLI_small_map.hpp
M source/blender/blenlib/BLI_small_set.hpp
===================================================================
diff --git a/source/blender/blenlib/BLI_array_lookup.hpp b/source/blender/blenlib/BLI_array_lookup.hpp
index 6573143f42f..5cfc4c76fb7 100644
--- a/source/blender/blenlib/BLI_array_lookup.hpp
+++ b/source/blender/blenlib/BLI_array_lookup.hpp
@@ -34,7 +34,7 @@ class ArrayLookup {
Mapping m_map;
uint m_length;
uint m_dummy_amount;
- uint m_max_length;
+ uint m_max_used_slots;
uint32_t m_slot_mask;
public:
@@ -161,7 +161,7 @@ class ArrayLookup {
private:
inline bool ensure_can_add(Item *array)
{
- if (LIKELY(m_length + m_dummy_amount < m_max_length)) {
+ if (LIKELY(m_length + m_dummy_amount < m_max_used_slots)) {
return false;
}
@@ -178,7 +178,7 @@ class ArrayLookup {
BLI_assert(count_bits_i(size) == 1);
m_map = Mapping(size);
m_map.fill(SLOT_EMPTY);
- m_max_length = m_map.size() * LOAD_FACTOR;
+ m_max_used_slots = m_map.size() * LOAD_FACTOR;
m_dummy_amount = 0;
m_slot_mask = size - 1;
}
@@ -210,6 +210,11 @@ class ArrayLookup {
}
}
+ inline float load_factor() const
+ {
+ return m_length / (float)m_map.size();
+ }
+
inline void first_slot(const Key &key, uint32_t *slot, uint32_t *perturb) const
{
uint32_t hash_value = Hash{}(key);
@@ -222,6 +227,82 @@ class ArrayLookup {
*slot = m_slot_mask & ((5 * *slot) + 1 + *perturb);
*perturb >>= PERTURB_SHIFT;
}
+
+ /* Produce Statistics
+ *******************************************/
+
+ private:
+ struct LookupStats {
+ SmallVector<uint> collisions_amount_distribution;
+ uint max_collisions = 0;
+ float average_collisions;
+ };
+
+ struct KeyLookupStats {
+ uint collisions_with_dummies = 0;
+ uint collisions_with_other_keys = 0;
+ bool found = false;
+ };
+
+ KeyLookupStats create_lookup_stats_for_key(Item *array, const Key &key) const
+ {
+ KeyLookupStats key_stats;
+
+ ITER_SLOTS(key, slot, state)
+ {
+ if (state == SLOT_DUMMY) {
+ key_stats.collisions_with_dummies++;
+ }
+ else if (state == SLOT_EMPTY) {
+ return key_stats;
+ }
+ else if (GetKey(array[state]) == key) {
+ key_stats.found = true;
+ return key_stats;
+ }
+ else {
+ key_stats.collisions_with_other_keys++;
+ }
+ }
+ }
+
+ LookupStats create_lookup_stats(Item *array) const
+ {
+ LookupStats stats;
+ stats.collisions_amount_distribution = SmallVector<uint>(m_map.size());
+ stats.collisions_amount_distribution.fill(0);
+
+ uint collisions_sum = 0;
+
+ for (uint i = 0; i < m_length; i++) {
+ KeyLookupStats key_stats = this->create_lookup_stats_for_key(array, GetKey(array[i]));
+ uint total_collisions = key_stats.collisions_with_dummies +
+ key_stats.collisions_with_other_keys;
+ stats.collisions_amount_distribution[total_collisions]++;
+ stats.max_collisions = MAX2(stats.max_collisions, total_collisions);
+ collisions_sum += total_collisions;
+ }
+ stats.average_collisions = collisions_sum / (float)m_length;
+ return stats;
+ }
+
+ public:
+ void print_lookup_stats(Item *array) const
+ {
+ LookupStats stats = this->create_lookup_stats(array);
+ std::cout << "Lookup Stats:\n";
+ std::cout << " Stored Keys: " << m_length << "\n";
+ std::cout << " Stored Dummies: " << m_dummy_amount << "\n";
+ std::cout << " Map Size: " << m_map.size() << "\n";
+ std::cout << " Load Factor: " << this->load_factor() << "\n";
+ std::cout << " Average Collisions: " << stats.average_collisions << "\n";
+ std::cout << " Max Lookup Collisions: " << stats.max_collisions << "\n\n";
+
+ for (uint i = 0; i <= stats.max_collisions; i++) {
+ std::cout << " " << i << " collision(s): " << stats.collisions_amount_distribution[i]
+ << "\n";
+ }
+ }
};
} /* namespace BLI */
diff --git a/source/blender/blenlib/BLI_small_map.hpp b/source/blender/blenlib/BLI_small_map.hpp
index 2fb23946768..f2edd9a7fad 100644
--- a/source/blender/blenlib/BLI_small_map.hpp
+++ b/source/blender/blenlib/BLI_small_map.hpp
@@ -120,6 +120,11 @@ template<typename K, typename V, uint N = 4> class SmallMap {
return m_entries.size();
}
+ void print_lookup_stats() const
+ {
+ m_lookup.print_lookup_stats(m_entries.begin());
+ }
+
ValueIterator values() const
{
return ValueIterator(*this);
diff --git a/source/blender/blenlib/BLI_small_set.hpp b/source/blender/blenlib/BLI_small_set.hpp
index 1ea0b320b45..55c4428235a 100644
--- a/source/blender/blenlib/BLI_small_set.hpp
+++ b/source/blender/blenlib/BLI_small_set.hpp
@@ -95,6 +95,11 @@ template<typename T, uint N = 4, typename Hash = std::hash<T>> class SmallSet {
{
return m_elements.end();
}
+
+ void print_lookup_stats()
+ {
+ m_lookup.print_lookup_stats(m_elements.begin());
+ }
};
} /* namespace BLI */
More information about the Bf-blender-cvs
mailing list