On 3/20/19 1:12 PM, Jakub Jelinek wrote:
Already in the PR71446 patch I used ugly and slow code to avoid allocating
memory in a hash_set all the time, even when it will be used only rarely and
in PR89767 I've reached it again.

While e.g. a vec is POD that even doesn't have a constructor and auto_vec
has quite a cheap ctor, hash_set/hash_map/hash_table actually allocate the
elements array right away.  I find that overkill for the cases where the
usual case is that the hash table will not be used and it handles only
something that happens rarely.  My PR71446 patch uses a pointer to hash_set
and performs new/delete if it is needed.

The following (so far untested) patch allows to construct
hash_{table,set,map} with no memory allocation, with the limitation that
only destruction, or size/elements methods can be used safely on that.
In order to switch such hash_* into normal use, there is a create method
(with optional number of initial elements), which is then called once and
afterwards it acts as any other hash_*.

Does this look reasonable, or do you have other proposals?

IMO if you need to guard usage with

+      if (some_type_hash_table.size () == 0)
+       some_type_hash_table.create ();

this isn't any better than

  /* Create the constexpr function table if necessary.  */
  if (constexpr_fundef_table == NULL)
    constexpr_fundef_table
      = hash_table<constexpr_fundef_hasher>::create_ggc (101);

Better I think would be to make the member functions handle null m_entries sensibly.

Jason

Reply via email to