From 38c3a2b5197a34f2e8a067ef6d7272168b8fdd28 Mon Sep 17 00:00:00 2001 From: Thomas Dionisi Date: Tue, 15 Sep 2026 17:25:28 +0200 Subject: [PATCH 1/2] [arcane,mesh] Make ItemInternalMap::resize() actually reserve Documented as "Resizes the hash table", its body was empty, so the five callers that announce a batch size were not served and the table grew by doubling. 5.3% gain on the mesh build, 8.8% on addCells itself, on a 640k-cell cartesian mesh at one rank. --- arcane/src/arcane/mesh/ItemInternalMap.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/arcane/src/arcane/mesh/ItemInternalMap.h b/arcane/src/arcane/mesh/ItemInternalMap.h index 03d36fcc97..f782d2653b 100644 --- a/arcane/src/arcane/mesh/ItemInternalMap.h +++ b/arcane/src/arcane/mesh/ItemInternalMap.h @@ -153,9 +153,18 @@ class ARCANE_MESH_EXPORT ItemInternalMap return (m_new_impl.find(key) != m_new_impl.end()); } - //! Resizes the hash table - void resize([[maybe_unused]] Int32 new_size, [[maybe_unused]] bool use_prime = false) + /*! + * \brief Makes room for \a new_size entries. + * + * Called before a batch of insertions by a family that knows how many items it + * is about to add, so that the table is sized once instead of growing by + * doubling and rehashing at each step. \a use_prime belonged to the previous + * implementation and is ignored. + */ + void resize(Int32 new_size, [[maybe_unused]] bool use_prime = false) { + if (new_size > 0) + m_new_impl.reserve(static_cast(new_size), false); } /*! From a7663fd0c27b67412dc1dd36fa5a3fa2c7b3745b Mon Sep 17 00:00:00 2001 From: Thomas Dionisi Date: Tue, 15 Sep 2026 17:25:28 +0200 Subject: [PATCH 2/2] [arcane,std] Size the generator's node table in buckets, not in entries The size given to a HashTableMapT is a number of buckets, and it rehashes past 0.85 * nb_bucket, so a table sized to the number of entries it will receive always outgrows itself. The mesh is unchanged. 9.4% gain on the initialisation of a 640k-cell cartesian mesh at one rank. --- arcane/src/arcane/std/CartesianMeshGenerator.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arcane/src/arcane/std/CartesianMeshGenerator.cc b/arcane/src/arcane/std/CartesianMeshGenerator.cc index f391f4d130..b5ab53fb81 100644 --- a/arcane/src/arcane/std/CartesianMeshGenerator.cc +++ b/arcane/src/arcane/std/CartesianMeshGenerator.cc @@ -660,7 +660,11 @@ generateMesh() // Création hash-table des noeuds et préparation de leurs uid UniqueArray nodes_unique_id(CheckedConvert::toInteger(own_nb_node_xyz)); - HashTableMapT nodes_infos(CheckedConvert::toInteger(own_nb_node_xyz), true); + // The size of a HashTableMapT is a number of buckets and not a number of + // entries: it rehashes as soon as its count passes 0.85 * nb_bucket, so the + // table is sized for the load factor and holds every node without rehashing. + const Int64 wanted_bucket = static_cast(own_nb_node_xyz / 0.85) + 1; + HashTableMapT nodes_infos(CheckedConvert::toInteger(wanted_bucket), true); // Calcule des infos blocs et des offset associés à tous les sub_domain_id IntegerUniqueArray sd_x_ibl, sd_x_obl; // Numéro et offset dans le bloc