Skip to content

Conversation

@Ivorforce
Copy link
Member

@Ivorforce Ivorforce commented Mar 17, 2025

This happens to allow us to deduplicate a bunch of operator== from String and Vector.
It might be possible to remove explicit overloads in those functions, instead relying on implicit conversions to Span, but this is a bit risky compilation wise and thus out of scope for this PR. Will revisit this in a future PR.

Span<char32_t> comparison to Span<char> is somewhat questionable from a String perspective, because it implicitly interprets the Span<char> as latin1, although it's usually ascii (still correct) or utf-8 (incorrect).
Still, from a Span perspective this is entirely reasonable, because individual elements report equality. It is up to callers to differentiate encodings if they matter.

Benchmark

This PR happens to optimize the equality checks of Packed*Array (fundamentally typed Vector). The reason is that the old implementation lacked a memcmp optimization. I naively benchmarked a ~4x improvement on my computer. The improvement is likely to be better on modern x86_64 machines, due to wider SIMD support (up to 16x).

I benchmarked this code:

extends Node2D

func _ready() -> void:
	var a := PackedInt32Array()
	a.resize(500000000)
	var b := PackedInt32Array()
	b.resize(500000000)

	for i in 20:
		a == b

This resulted in:

 ❯ hyperfine -m5 -iw1 "bin/godot.macos.editor.arm64.master --path /Users/lukas/new-game-project --quit" "bin/godot.macos.editor.arm64 --path /Users/lukas/new-game-project --quit"
Benchmark 1: bin/godot.macos.editor.arm64.master --path /Users/lukas/new-game-project --quit
  Time (mean ± σ):     11.970 s ±  0.092 s    [User: 10.632 s, System: 0.543 s]
  Range (min … max):   11.856 s … 12.081 s    5 runs

Benchmark 2: bin/godot.macos.editor.arm64 --path /Users/lukas/new-game-project --quit
  Time (mean ± σ):      3.168 s ±  0.035 s    [User: 1.863 s, System: 0.512 s]
  Range (min … max):    3.129 s …  3.221 s    5 runs

Summary
  bin/godot.macos.editor.arm64 --path /Users/lukas/new-game-project --quit ran
    3.78 ± 0.05 times faster than bin/godot.macos.editor.arm64.master --path /Users/lukas/new-game-project --quit

@Ivorforce Ivorforce requested review from a team as code owners March 17, 2025 17:13
@AThousandShips AThousandShips added this to the 4.x milestone Mar 17, 2025
@Ivorforce Ivorforce force-pushed the span-equality branch 3 times, most recently from 67696c2 to 901a5bf Compare March 17, 2025 17:53
Copy link
Contributor

@kiroxas kiroxas left a comment

Choose a reason for hiding this comment

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

Make sense to me and would avoid to have to construct strings to compare char* against spans (useful for other PRS )

Exchange duplicate equality iteration implementations across `Vector` and `String` with the `Span` version, for a speed boost.
Copy link
Member

@lawnjelly lawnjelly left a comment

Choose a reason for hiding this comment

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

Looks sensible, the more we can use span for these comparisons the better imo.

@Ivorforce Ivorforce modified the milestones: 4.x, 4.6 Nov 15, 2025
@Repiteo Repiteo merged commit 910133f into godotengine:master Nov 17, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Nov 17, 2025

Thanks!

@Ivorforce Ivorforce deleted the span-equality branch November 17, 2025 17:37
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.

5 participants