bevy/crates
scottmcm a902ea6f85
Save an instruction in EntityHasher (#10648)
# Objective

Keep essentially the same structure of `EntityHasher` from #9903, but
rephrase the multiplication slightly to save an instruction.

cc @superdump 
Discord thread:
https://discord.com/channels/691052431525675048/1172033156845674507/1174969772522356756

## Solution

Today, the hash is
```rust
        self.hash = i | (i.wrapping_mul(FRAC_U64MAX_PI) << 32);
```
with `i` being `(generation << 32) | index`.

Expanding things out, we get
```rust
i | ( (i * CONST) << 32 )
= (generation << 32) | index | ((((generation << 32) | index) * CONST) << 32)
= (generation << 32) | index | ((index * CONST) << 32)  // because the generation overflowed
= (index * CONST | generation) << 32 | index
```

What if we do the same thing, but with `+` instead of `|`? That's almost
the same thing, except that it has carries, which are actually often
better in a hash function anyway, since it doesn't saturate. (`|` can be
dangerous, since once something becomes `-1` it'll stay that, and
there's no mixing available.)

```rust
(index * CONST + generation) << 32 + index
= (CONST << 32 + 1) * index + generation << 32
= (CONST << 32 + 1) * index + (WHATEVER << 32 + generation) << 32 // because the extra overflows and thus can be anything
= (CONST << 32 + 1) * index + ((CONST * generation) << 32 + generation) << 32 // pick "whatever" to be something convenient
= (CONST << 32 + 1) * index + ((CONST << 32 + 1) * generation) << 32
= (CONST << 32 + 1) * index +((CONST << 32 + 1) * (generation << 32)
= (CONST << 32 + 1) * (index + generation << 32)
= (CONST << 32 + 1) * (generation << 32 | index)
= (CONST << 32 + 1) * i
```

So we can do essentially the same thing using a single multiplication
instead of doing multiply-shift-or.

LLVM was already smart enough to merge the shifting into a
multiplication, but this saves the extra `or`:

![image](https://github.com/bevyengine/bevy/assets/18526288/d9396614-2326-4730-abbe-4908c01b5ace)
<https://rust.godbolt.org/z/MEvbz4eo4>

It's a very small change, and often will disappear in load latency
anyway, but it's a couple percent faster in lookups:

![image](https://github.com/bevyengine/bevy/assets/18526288/c365ec85-6adc-4f6d-8fa6-a65146f55a75)

(There was more of an improvement here before #10558, but with `to_bits`
being a single `qword` load now, keeping things mostly as it is turned
out to be better than the bigger changes I'd tried in #10605.)

---

## Changelog

(Probably skip it)

## Migration Guide

(none needed)
2023-11-28 12:37:30 +00:00
..
bevy_a11y Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_animation Enable clippy::undocumented_unsafe_blocks warning across the workspace (#10646) 2023-11-21 02:06:24 +00:00
bevy_app Wait until FixedUpdate can see events before dropping them (#10077) 2023-11-26 23:04:41 +00:00
bevy_asset Add clippy::manual_let_else at warn level to lints (#10684) 2023-11-28 04:15:27 +00:00
bevy_audio Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_core Split WorldQuery into WorldQueryData and WorldQueryFilter (#9918) 2023-11-28 03:56:07 +00:00
bevy_core_pipeline Add clippy::manual_let_else at warn level to lints (#10684) 2023-11-28 04:15:27 +00:00
bevy_derive Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_diagnostic Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_dylib Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_dynamic_plugin Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_ecs Save an instruction in EntityHasher (#10648) 2023-11-28 12:37:30 +00:00
bevy_ecs_compile_fail_tests Split WorldQuery into WorldQueryData and WorldQueryFilter (#9918) 2023-11-28 03:56:07 +00:00
bevy_encase_derive Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_gilrs Add [lints] table, fix adding #![allow(clippy::type_complexity)] everywhere (#10011) 2023-11-18 20:58:48 +00:00
bevy_gizmos Bind group layout entries (#10224) 2023-11-28 04:00:49 +00:00
bevy_gltf Fix GLTF scene dependencies and make full scene renders predictable (#10745) 2023-11-27 22:42:28 +00:00
bevy_hierarchy Split WorldQuery into WorldQueryData and WorldQueryFilter (#9918) 2023-11-28 03:56:07 +00:00
bevy_input Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_internal Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_log Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_macro_utils Allow #[derive(Bundle)] on tuple structs (take 3) (#10561) 2023-11-21 01:09:16 +00:00
bevy_macros_compile_fail_tests Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_math Use minor and major radii for Torus primitive shape (#10643) 2023-11-21 01:49:35 +00:00
bevy_mikktspace Enable clippy::undocumented_unsafe_blocks warning across the workspace (#10646) 2023-11-21 02:06:24 +00:00
bevy_pbr prepass vertex shader always outputs world position (#10657) 2023-11-28 12:13:28 +00:00
bevy_ptr Enable clippy::undocumented_unsafe_blocks warning across the workspace (#10646) 2023-11-21 02:06:24 +00:00
bevy_reflect Add clippy::manual_let_else at warn level to lints (#10684) 2023-11-28 04:15:27 +00:00
bevy_reflect_compile_fail_tests Improve TypeUuid's derive macro error messages (#9315) 2023-10-02 12:42:01 +00:00
bevy_render Add clippy::manual_let_else at warn level to lints (#10684) 2023-11-28 04:15:27 +00:00
bevy_scene Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_sprite Bind group layout entries (#10224) 2023-11-28 04:00:49 +00:00
bevy_tasks bump bevy_tasks futures-lite to 2.0.1 (#10675) 2023-11-24 00:11:02 +00:00
bevy_text Standardize toml format with taplo (#10594) 2023-11-21 01:04:14 +00:00
bevy_time Wait until FixedUpdate can see events before dropping them (#10077) 2023-11-26 23:04:41 +00:00
bevy_transform Enable clippy::undocumented_unsafe_blocks warning across the workspace (#10646) 2023-11-21 02:06:24 +00:00
bevy_ui Provide GlobalsUniform in UiMaterial shaders (#10739) 2023-11-28 12:08:28 +00:00
bevy_utils Save an instruction in EntityHasher (#10648) 2023-11-28 12:37:30 +00:00
bevy_window add new event WindowOccluded from winit (#10735) 2023-11-26 21:58:54 +00:00
bevy_winit add new event WindowOccluded from winit (#10735) 2023-11-26 21:58:54 +00:00