Thread overview
How to get hash value of an object?
Nov 27, 2016
panmengh
Dec 04, 2016
Era Scarecrow
Dec 11, 2016
Seb
November 27, 2016
How to get hash value of an object?

Use hashOf? or typeid(T).getHash(&o)?

I test with the following code:

System:
windows 10

dmd --version
DMD32 D Compiler v2.072.0 (official download version)

ldc2 --version
LDC - the LLVM D compiler (1.1.0git-62a2252) (the latest git master version)
  based on DMD v2.071.2 and LLVM 3.9.1git

import std.stdio;

void main()
{
    string[string] a;
    string[string] b0;

    writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), "\t\t\t",
        b0.hashOf(), "\t\t",typeid(typeof(b0)).getHash(&b0), "  ", a,);

    a["1"] = "1";
    string[string] b1 = ["1":"1"];
    writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), "\t\t",
        b1.hashOf(), "\t\t",typeid(typeof(b1)).getHash(&b1), "  ", a,);

    a["9"] = "9";
    string[string] b2 = ["1":"1", "9":"9"];
    writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), "\t\t\t",
        b2.hashOf(), "\t\t",typeid(typeof(b2)).getHash(&b2), "  ", a,);

    a["3"] = "3";
    string[string] b3 = ["1":"1", "9":"9", "3":"3"];
    writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), "\t\t",
        b3.hashOf(), "\t\t",typeid(typeof(b3)).getHash(&b3), "  ", a,);

    a.remove("1");
    a["1"] = "1";
    string[string] b4 = ["1":"1", "9":"9", "3":"3"];
    writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), "\t\t",
        b3.hashOf(), "\t\t",typeid(typeof(b4)).getHash(&b4), "  ", a,);
}

Output:
dub --compiler=dmd -a=x86_64
Running .\test2.exe
1669671676      0           1669671676  0           []
732702303       2197205690  683765274   3388425732  ["1":"1"]
732702303       0           912895782   0           ["1":"1", "9":"9"]
732702303       2197205690  4139255736  3388425732  ["3":"3", "1":"1", "9":"9"]
732702303       2197205690  4139255736  3388425732  ["3":"3", "1":"1", "9":"9"]

test2.exe (second run)
1669671676      0           1669671676  0           []
1608602074      122060002   2487796584  31054674    ["1":"1"]
1608602074      0           3256818953  0           ["1":"1", "9":"9"]
1608602074      122060002   667025292   31054674    ["3":"3", "1":"1", "9":"9"]
1608602074      122060002   667025292   31054674    ["3":"3", "1":"1", "9":"9"]

dub --compiler=ldc2 -a=x86_64
Running .\test2.exe
593689054       0           593689054   0           []
1747365348      1899073920  1747365348  1899073920  ["1":"1"]
3252326176      0           3252326176  0           ["1":"1", "9":"9"]
492636279       1899073920  492636279   1899073920  ["3":"3", "1":"1", "9":"9"]
492636279       1899073920  492636279   1899073920  ["3":"3", "1":"1", "9":"9"]

test2.exe (second run)
593689054       0           593689054   0           []
1747365348      2353409518  1747365348  2353409518  ["1":"1"]
3252326176      0           3252326176  0           ["1":"1", "9":"9"]
492636279       2353409518  492636279   2353409518  ["3":"3", "1":"1", "9":"9"]
492636279       2353409518  492636279   2353409518  ["3":"3", "1":"1", "9":"9"]

Does only hashOf with ldc2 return the right value?


November 28, 2016
On 11/27/16 2:10 AM, panmengh wrote:
> How to get hash value of an object?
>
> Use hashOf? or typeid(T).getHash(&o)?

hashOf is kind of this horrible hacky thing that nobody should be using. It literally takes whatever you pass it and hashes the local bytes. It doesn't care about opHash or if any of those bytes are actually references to the things you want hashed. In fact, for class references, it just hashes the bytes that point at the class. Useless.

Long story short, use typeid(T).getHash(&o).

> Does only hashOf with ldc2 return the right value?

If it does, that's a coincidence. Happened to allocate in the same place.

-Steve
December 04, 2016
On Tuesday, 29 November 2016 at 00:05:31 UTC, Steven Schveighoffer wrote:
> hashOf is kind of this horrible hacky thing that nobody should be using. It literally takes whatever you pass it and hashes the local bytes.

 Ugg... Anything with pointers, classes or arrays will have huge problems with consistency; While anything with fixed static arrays or pure value-types will result in proper values.

 I'd almost prefer an option to get hashOf all inner object types and then xor them all together. Although this could make for a very complex hashOf depending on implementation of the object.

> Long story short, use typeid(T).getHash(&o).

 Hmmm maybe make any struct have hashOf disabled if it includes any pointers or dynamic arrays or inner objects that can't get a proper hash of it. While it will break things, at least you know what can't be hashed when you try to use it. Or maybe have that as a compiler option for those wanting to make use of that.
December 11, 2016
On Sunday, 4 December 2016 at 13:17:09 UTC, Era Scarecrow wrote:
> On Tuesday, 29 November 2016 at 00:05:31 UTC, Steven Schveighoffer wrote:
>> hashOf is kind of this horrible hacky thing that nobody should be using. It literally takes whatever you pass it and hashes the local bytes.
>
>  Ugg... Anything with pointers, classes or arrays will have huge problems with consistency; While anything with fixed static arrays or pure value-types will result in proper values.

For the record: it was a regression and has been fixed with https://github.com/dlang/druntime/pull/1707 and thus should be part of the next point release.