Skip to content

Conversation

dementive
Copy link
Contributor

The Color type has no hash function in HashMapHasherDefault, it still works right now but it only works because color gets implicitly converted to a String.

I had some code that was insanely slow for no good reason so I ran it through callgrind to figure out what was going on and I saw this in Kcachegrind:

image

40 billion instructions from String allocations when doing Color HashMap lookups didn't really make any sense, Color should have nothing to do with String. So I looked into the HashMap lookup function and sure enough there was no Color hash function, which caused keys of Color type to get implicitly converted to a String and then it called the String hash function.

Just by adding this Color hash function my startup time went from around 5 seconds to about half a second.

@dementive dementive requested a review from a team as a code owner June 8, 2025 18:56
Copy link
Member

@Ivorforce Ivorforce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can confirm this is a problem.
I ran across it in #106434, and fixed it in the same way there.
Unfortunately, that PR hasn't received reviews yet, so it might be a while till it's merged. Makes sense to merge the fix already.

h = hash_murmur3_one_real(p_vec.w, h);
return hash_fmix32(h);
}
static _FORCE_INLINE_ uint32_t hash(const Color &p_vec) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_FORCE_INLINE_ is not appropriate here.
I assume you got there since you copied it from other functions' signatures, but it also wasn't appropriate there either, just nobody fixed this yet :)

Suggested change
static _FORCE_INLINE_ uint32_t hash(const Color &p_vec) {
static uint32_t hash(const Color &p_vec) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that every other method has it, I think it's better for code adding the missing one to be consistent.

If the _FORCE_INLINE_ is wrong in the other methods, it should be removed in a separate PR (and then this one can be removed too).

@Ivorforce Ivorforce added this to the 4.5 milestone Jun 8, 2025
@akien-mga akien-mga merged commit 9e02194 into godotengine:master Jun 8, 2025
20 checks passed
@akien-mga
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants