Skip to content

[vector_math] Write out parameters once through setValues - #38

Open
spydon wants to merge 1 commit into
flutter:mainfrom
spydon:fix/vector-write-out-parameters-once
Open

[vector_math] Write out parameters once through setValues#38
spydon wants to merge 1 commit into
flutter:mainfrom
spydon:fix/vector-write-out-parameters-once

Conversation

@spydon

@spydon spydon commented Aug 30, 2026

Copy link
Copy Markdown

Makes the Vector2, Vector3 and Vector4 members that take an out/result parameter compute their result first and write it with a single setValues call:

  • normalizeInto(out) did out..setFrom(this)..normalize(): one pass to copy the components and a second pass to read them back, compute the length and scale them. It now computes the normalized components from this and writes them once; the zero vector is still copied unchanged.
  • min, max and mix assigned each component through a separate setter call (result..x = …..y = …). They now make one setValues call.
  • copyInto(arg) wrote the target's storage field by field; it is aligned with the same single setValues pattern.

Numeric results are identical (verified by the benchmark checksums and the test suite). vector_math_64 was regenerated with tool/generate_vector_math_64.dart; only the vector files are included, because the generator also produces unrelated diffs in intersection_result.dart and quaternion.dart (those 64-bit files were hand-edited after generation), so they are left untouched here.

A new test, test/out_parameter_test.dart, covers the rewritten members for all three classes: results for normalizeInto (including the zero-length vector and v.normalizeInto(v) aliasing), copyInto, min, max and mix.

Benchmark

Standalone benchmark (not committed) compiled with dart compile exe against main and against this branch, on macOS arm64; 4096 vectors per case, each binary run five times alternately, values are min/median/max of the runs in nanoseconds per call.

Target Member main this PR reading
Vector2 normalizeInto 2.55 / 2.59 / 2.61 2.37 / 2.39 / 2.55 ~8% faster
Vector2 copyInto 1.06 / 1.08 / 1.09 1.05 / 1.08 / 1.14 unchanged
Vector2 min 1.71 / 1.72 / 1.73 1.58 / 1.58 / 1.64 ~8% faster, no overlap
Vector2 max 1.69 / 1.73 / 1.73 1.58 / 1.59 / 1.61 ~8% faster, no overlap
Vector2 mix 1.78 / 1.82 / 1.82 1.67 / 1.68 / 1.70 ~8% faster, no overlap
Vector3 normalizeInto 2.94 / 3.05 / 3.19 2.68 / 2.68 / 2.87 ~12% faster
Vector3 copyInto 1.26 / 1.27 / 1.37 1.24 / 1.26 / 1.37 unchanged
Vector3 min 2.14 / 2.18 / 2.22 1.93 / 1.95 / 2.08 ~11% faster, no overlap
Vector3 max 2.14 / 2.17 / 2.19 1.93 / 1.94 / 2.08 ~11% faster, no overlap
Vector3 mix 3.00 / 3.06 / 3.23 2.90 / 2.91 / 3.11 ~5% faster
Vector4 normalizeInto 3.63 / 3.65 / 3.72 3.02 / 3.06 / 3.08 ~16% faster, no overlap
Vector4 copyInto 1.35 / 1.37 / 1.41 1.35 / 1.37 / 1.39 unchanged
Vector4 min 3.29 / 3.33 / 3.41 3.10 / 3.16 / 3.33 ~5% faster
Vector4 max 3.28 / 3.28 / 3.55 3.09 / 3.14 / 3.58 ~4% faster
Vector4 mix 3.50 / 3.52 / 3.75 3.21 / 3.22 / 3.47 ~9% faster

The gains are AOT-specific. The same benchmark compiled with dart compile js -O4 and run in node measures neutral: every case is within about 2% with overlapping ranges. Both builds produce identical checksums on both platforms.

Fixes flutter/flutter#192041

Pre-Review Checklist

https://claude.ai/code/session_01PixXaRTPs8v1P2mQF2QHGG

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

@github-actions github-actions Bot added p: vector_math triage-framework Should be looked at in framework triage labels Aug 30, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request updates Vector2, Vector3, and Vector4 (both 32-bit and 64-bit implementations) so that normalizeInto, copyInto, min, max, and mix write to their output parameters exactly once using setValues. It also adds tests to verify this behavior for subclass observation. The review feedback highlights multiple instances where newly introduced lines exceed the 80-character limit specified in the style guide, suggesting wrapping arguments to improve readability.

Comment thread packages/vector_math/lib/src/vector_math/vector2.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math_64/vector2.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math/vector3.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math/vector3.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math_64/vector3.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math_64/vector3.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math/vector4.dart Outdated
Comment thread packages/vector_math/lib/src/vector_math_64/vector4.dart Outdated
normalizeInto wrote its target with setFrom followed by a normalize
pass, min, max and mix assigned each component through a separate
setter, and copyInto wrote the target's storage field by field. The
Vector2, Vector3 and Vector4 members that take an out or result
parameter now compute their result first and write it with a single
setValues call, which measures 6 to 17 percent faster in AOT for
normalizeInto, min, max and mix while producing identical results.

Claude-Session: https://claude.ai/code/session_01PixXaRTPs8v1P2mQF2QHGG
@spydon
spydon force-pushed the fix/vector-write-out-parameters-once branch from 69d5fdb to f0f0e94 Compare August 30, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p: vector_math triage-framework Should be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[vector_math] normalizeInto, min, max and mix write their out parameters inefficiently

1 participant