Skip to content

Commit

Permalink
speed up hash(::Symbol)
Browse files Browse the repository at this point in the history
Since symbols are pre-hashed, add a fast path to return the value directly.
  • Loading branch information
JeffBezanson authored and johanmon committed Jul 5, 2021
1 parent 7e626dc commit 40e339a
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 2 deletions.
2 changes: 2 additions & 0 deletions base/hashing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ hash(w::WeakRef, h::UInt) = hash(w.value, h)

hash(@nospecialize(x), h::UInt) = hash_uint(3h - objectid(x))

hash(x::Symbol) = objectid(x)

## core data hashing functions ##

function hash_64_64(n::UInt64)
Expand Down
11 changes: 10 additions & 1 deletion src/ccall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1711,7 +1711,16 @@ static jl_cgval_t emit_ccall(jl_codectx_t &ctx, jl_value_t **args, size_t nargs)
else if (is_libjulia_func(jl_object_id) && nccallargs == 1 &&
rt == (jl_value_t*)jl_ulong_type) {
jl_cgval_t val = argv[0];
if (!val.isboxed) {
if (val.typ == (jl_value_t*)jl_symbol_type) {
JL_GC_POP();
const int hash_offset = offsetof(jl_sym_t, hash);
Value *ph1 = emit_bitcast(ctx, boxed(ctx, val), T_psize);
Value *ph2 = ctx.builder.CreateInBoundsGEP(ph1, ConstantInt::get(T_size, hash_offset / sizeof(size_t)));
LoadInst *hashval = ctx.builder.CreateAlignedLoad(ph2, Align(sizeof(size_t)));
tbaa_decorate(tbaa_const, hashval);
return mark_or_box_ccall_result(ctx, hashval, retboxed, rt, unionall, static_rt);
}
else if (!val.isboxed) {
// If the value is not boxed, try to compute the object id without
// reboxing it.
auto T_pint8_derived = PointerType::get(T_int8, AddressSpace::Derived);
Expand Down
4 changes: 3 additions & 1 deletion src/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ static jl_sym_t *symtab = NULL;

static uintptr_t hash_symbol(const char *str, size_t len) JL_NOTSAFEPOINT
{
return memhash(str, len) ^ ~(uintptr_t)0/3*2;
uintptr_t oid = memhash(str, len) ^ ~(uintptr_t)0/3*2;
// compute the same hash value as v1.6 and earlier, which used `hash_uint(3h - objectid(sym))`
return inthash(-oid);
}

static size_t symbol_nbytes(size_t len) JL_NOTSAFEPOINT
Expand Down

0 comments on commit 40e339a

Please sign in to comment.