Skip to content

Commit

Permalink
Speed up integer-vector hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
heyx3 committed Jun 24, 2022
1 parent c4bf1b9 commit 7bf0f75
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
24 changes: 20 additions & 4 deletions WFC++/Vector2i.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ namespace WFC

Vector2i operator-() const { return Vector2i(-x, -y); }

bool operator==(const Vector2i& v) const { return (x == v.x) && (y == v.y); }
bool operator!=(const Vector2i& v) const { return (x != v.x) || (y != v.y); }
bool operator==(const Vector2i& v) const
{
static_assert(sizeof(Vector2i) == 2 * sizeof(int),
"Vector2i has some byte padding");
return memcmp(this, &v, sizeof(Vector2i)) == 0;
}
bool operator!=(const Vector2i& v) const { return !operator==(v); }


Vector2i LessX() const { return Vector2i(x - 1, y); }
Expand All @@ -104,8 +109,19 @@ namespace WFC
// assuming the "pivot" is halfway between the origin and "size".
Vector2i Transform(Transformations trnsf, Vector2i size) const;

uint32_t GetHashcode() const { return Math::Hash(static_cast<int32_t>(x),
static_cast<int32_t>(y)); }
uint32_t GetHashcode() const
{
//This seems to be a significant bottleneck, so I spent some time thinking
// and searching for a fast way to hash integers.
//Reference: https://stackoverflow.com/questions/30032950/creating-a-hash-seed-value-from-2-integers-fast
//It works better with high bits than low ones,
// so I bitwise-invert the components before using them.
int a = ~x,
b = ~y;
a ^= b;
a = (a << 24) + (a * 0x193);
return a;
}
};


Expand Down
16 changes: 11 additions & 5 deletions WFC++/Vector3i.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,13 @@ namespace WFC

Vector3i operator-() const { return Vector3i(-x, -y, -z); }

bool operator==(const Vector3i& v) const { return (x == v.x) && (y == v.y) && (z == v.z); }
bool operator!=(const Vector3i& v) const { return (x != v.x) || (y != v.y) || (z != v.z); }
bool operator==(const Vector3i& v) const
{
static_assert(sizeof(Vector3i) == 3 * sizeof(int),
"Vector3i has some byte padding");
return memcmp(this, &v, sizeof(Vector3i)) == 0;
}
bool operator!=(const Vector3i& v) const { return !operator==(v); }


Vector3i LessX() const { return Vector3i(x - 1, y, z); }
Expand All @@ -66,9 +71,10 @@ namespace WFC
Vector3i LessZ() const { return Vector3i(x, y, z - 1); }
Vector3i MoreZ() const { return Vector3i(x, y, z + 1); }

uint32_t GetHashcode() const { return Vector2i(static_cast<uint32_t>(z),
Vector2i(x, y).GetHashcode()
).GetHashcode(); }
uint32_t GetHashcode() const
{
return Vector2i(Vector2i(x, y).GetHashcode(), z).GetHashcode();
}
};


Expand Down
16 changes: 12 additions & 4 deletions WFC++/Vector4i.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,12 @@ namespace WFC

Vector4i operator-() const { return Vector4i(-x, -y, -z, -w); }

bool operator==(const Vector4i& v) const { return (x == v.x) && (y == v.y) && (z == v.z) && (w == v.w); }
bool operator==(const Vector4i& v) const
{
static_assert(sizeof(Vector4i) == 4 * sizeof(int),
"Vector4i has some byte padding");
return memcmp(this, &v, sizeof(Vector4i)) == 0;
}
bool operator!=(const Vector4i& v) const { return !operator==(v); }


Expand All @@ -68,9 +73,12 @@ namespace WFC
Vector4i LessW() const { return Vector4i(x, y, z, w - 1); }
Vector4i MoreW() const { return Vector4i(x, y, z, w + 1); }

uint32_t GetHashcode() const { return Vector2i(Vector2i(x, y).GetHashcode(),
Vector2i(z, w).GetHashcode()
).GetHashcode(); }
uint32_t GetHashcode() const
{
auto a = Vector2i(x, y).GetHashcode(),
b = Vector2i(x, y ).GetHashcode();
return Vector2i(static_cast<int32_t>(a), static_cast<int32_t>(b)).GetHashcode();
}
};


Expand Down

0 comments on commit 7bf0f75

Please sign in to comment.