Skip to content

feat: replace Key internals with DefaultHasher for allocation-free comparison#4006

Open
Madoshakalaka wants to merge 1 commit intomasterfrom
key-defaulthasher
Open

feat: replace Key internals with DefaultHasher for allocation-free comparison#4006
Madoshakalaka wants to merge 1 commit intomasterfrom
key-defaulthasher

Conversation

@Madoshakalaka
Copy link
Member

@Madoshakalaka Madoshakalaka commented Feb 26, 2026

Description

Replaces Key's internal Rc with a NonZeroU64 hash computed via DefaultHasher, as discussed in #3205 and the earlier PR #2616.

  • Key comparison is now a single u64 == instead of string comparison
  • Numeric key creation avoids heap allocation in release builds
  • Option is niche-optimized to the same size as Key (8 bytes)
  • Debug builds retain the original string for diagnostics

closes #3205

Checklist

  • I have reviewed my own code
  • I have added tests

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Visit the preview URL for this PR (updated for commit 61913af):

https://yew-rs-api--pr4006-key-defaulthasher-qyp24pfl.web.app

(expires Thu, 05 Mar 2026 08:37:08 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Benchmark - core

Yew Master

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.796 ns      │ 3.339 ns      │ 2.8 ns        │ 2.809 ns      │ 100     │ 1000000000

Pull Request

vnode           fastest       │ slowest       │ median        │ mean          │ samples │ iters
╰─ vnode_clone  2.775 ns      │ 4.171 ns      │ 2.781 ns      │ 2.801 ns      │ 100     │ 1000000000

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Benchmark - SSR

Yew Master

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 291.034 292.337 291.510 0.424
Hello World 10 493.406 497.952 495.679 1.547
Function Router 10 1656.386 1682.497 1667.861 8.404
Concurrent Task 10 1005.696 1007.875 1006.979 0.682
Many Providers 10 1091.915 1127.945 1105.751 12.546

Pull Request

Details
Benchmark Round Min (ms) Max (ms) Mean (ms) Standard Deviation
Baseline 10 310.748 311.931 311.148 0.332
Hello World 10 478.650 489.151 481.598 4.134
Function Router 10 1620.751 1652.191 1634.345 10.628
Concurrent Task 10 1005.796 1007.811 1006.942 0.684
Many Providers 10 1119.223 1157.298 1136.642 12.296

@github-actions
Copy link

github-actions bot commented Feb 26, 2026

Size Comparison

Details
examples master (KB) pull request (KB) diff (KB) diff (%)
async_clock 96.823 96.289 -0.534 -0.552%
boids 165.482 164.997 -0.485 -0.293%
communication_child_to_parent 89.899 89.470 -0.430 -0.478%
communication_grandchild_with_grandparent 100.772 100.378 -0.395 -0.392%
communication_grandparent_to_grandchild 97.273 96.843 -0.431 -0.443%
communication_parent_to_child 87.314 86.878 -0.437 -0.500%
contexts 103.035 102.655 -0.380 -0.369%
counter 84.037 83.553 -0.484 -0.576%
counter_functional 85.410 84.940 -0.470 -0.550%
dyn_create_destroy_apps 87.122 86.666 -0.456 -0.523%
file_upload 96.566 96.013 -0.554 -0.573%
function_delayed_input 90.901 90.434 -0.468 -0.515%
function_memory_game 168.782 168.404 -0.378 -0.224%
function_router 326.337 325.397 -0.939 -0.288%
function_todomvc 160.736 160.485 -0.251 -0.156%
futures 232.128 231.617 -0.511 -0.220%
game_of_life 102.119 101.779 -0.340 -0.333%
immutable 244.170 242.980 -1.189 -0.487%
inner_html 78.616 78.141 -0.476 -0.605%
js_callback 107.492 107.026 -0.466 -0.433%
keyed_list 177.171 176.745 -0.426 -0.240%
mount_point 81.754 81.294 -0.460 -0.563%
nested_list 110.428 109.807 -0.621 -0.562%
node_refs 89.300 88.782 -0.518 -0.580%
password_strength 1725.986 1725.342 -0.645 -0.037%
portals 90.777 90.336 -0.441 -0.486%
router 296.723 296.444 -0.278 -0.094%
suspense 110.946 110.582 -0.364 -0.328%
timer 86.637 86.141 -0.496 -0.573%
timer_functional 96.147 94.212 -1.936 -2.013%
todomvc 139.338 139.111 -0.227 -0.163%
two_apps 83.903 83.471 -0.433 -0.516%
web_worker_fib 133.659 133.119 -0.540 -0.404%
web_worker_prime 184.450 183.801 -0.649 -0.352%
webgl 81.250 80.749 -0.501 -0.617%

⚠️ The following example has changed its size significantly:

examples master (KB) pull request (KB) diff (KB) diff (%)
timer_functional 96.147 94.212 -1.936 -2.013%

@Madoshakalaka
Copy link
Member Author

Looks like a pure win, every example shrunk, no performance regression, cleaner semantics. Recall that the original PR #2616 was rejected partly due to binary size increases of 1-8 KB. We all good here.

@Madoshakalaka Madoshakalaka marked this pull request as ready for review February 26, 2026 08:32
github-actions[bot]
github-actions bot previously approved these changes Feb 26, 2026
…mparison (#3205)

BREAKING CHANGE: Key no longer implements Deref<Target=str>.
BREAKING CHANGE: Keys from different types with the same string representation
are no longer equal (e.g. Key::from("0") != Key::from(0u64)).
BREAKING CHANGE: Display in release mode shows #<hash> instead of the original value.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make Key avoid an allocation, make it faster to compare than Strings

1 participant