Skip to content

Commit

Permalink
Use 1 byte hint for ar_table [Feature #15602]
Browse files Browse the repository at this point in the history
On ar_table, Do not keep a full-length hash value (FLHV, 8 bytes)
but keep a 1 byte hint from a FLHV (lowest byte of FLHV).
An ar_table only contains at least 8 entries, so hints consumes
8 bytes at most. We can store hints in RHash::ar_hint.

On 32bit CPU, we use 4 entries ar_table.

The advantages:
* We don't need to keep FLHV so ar_table only consumes
  16 bytes (VALUEs of key and value) * 8 entries = 128 bytes.
* We don't need to scan ar_table, but only need to check hints
  in many cases. Especially we don't need to access ar_table
  if there is no match entries (in many cases).
  It will increase memory cache locality.

The disadvantages:
* This technique can increase `#eql?` time because hints can
  conflicts (in theory, it conflicts once in 256 times).
  It can introduce incompatibility if there is a object x where
  x.eql? returns true even if hash values are different.
  I believe we don't need to care such irregular case.
* We need to re-calculate FLHV if we need to switch from ar_table
  to st_table (e.g. exceeds 8 entries).
  It also can introduce incompatibility, on mutating key objects.
  I believe we don't need to care such irregular case too.

Add new debug counters to measure the performance:
* artable_hint_hit - hint is matched and eql?#=>true
* artable_hint_miss - hint is not matched but eql?#=>false
* artable_hint_notfound - lookup counts
  • Loading branch information
Koichi Sasada authored and ko1 committed Jul 31, 2019
1 parent ebd398a commit 72825c3
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 153 deletions.
6 changes: 5 additions & 1 deletion debug_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,6 @@ RB_DEBUG_COUNTER(obj_hash_g8)
RB_DEBUG_COUNTER(obj_hash_ar)
RB_DEBUG_COUNTER(obj_hash_st)
RB_DEBUG_COUNTER(obj_hash_transient)

RB_DEBUG_COUNTER(obj_hash_force_convert)

RB_DEBUG_COUNTER(obj_struct_embed)
Expand Down Expand Up @@ -262,6 +261,11 @@ RB_DEBUG_COUNTER(obj_iclass_ptr)
RB_DEBUG_COUNTER(obj_class_ptr)
RB_DEBUG_COUNTER(obj_module_ptr)

/* ar_table */
RB_DEBUG_COUNTER(artable_hint_hit)
RB_DEBUG_COUNTER(artable_hint_miss)
RB_DEBUG_COUNTER(artable_hint_notfound)

/* heap function counts
*
* * heap_xmalloc/realloc/xfree: call counts
Expand Down
2 changes: 1 addition & 1 deletion ext/objspace/objspace_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ dump_object(VALUE obj, struct dump_config *dc)

case T_HASH:
dump_append(dc, ", \"size\":%"PRIuSIZE, (size_t)RHASH_SIZE(obj));
if (FL_TEST(obj, HASH_PROC_DEFAULT))
if (FL_TEST(obj, RHASH_PROC_DEFAULT))
dump_append(dc, ", \"default\":\"%#"PRIxVALUE"\"", RHASH_IFNONE(obj));
break;

Expand Down
Loading

0 comments on commit 72825c3

Please sign in to comment.