From 545bf9bb2f9ef0f47873f2e72aac77c52aad0dc1 Mon Sep 17 00:00:00 2001 From: Daniel Wennberg Date: Tue, 24 Sep 2024 17:11:48 -0700 Subject: [PATCH] Add fast path for when all struct fields are set --- src/compiler.jl | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/compiler.jl b/src/compiler.jl index 9416ebea92..2438945b3a 100644 --- a/src/compiler.jl +++ b/src/compiler.jl @@ -1970,19 +1970,31 @@ end return y end - flds = Vector{Any}(undef, nf) - for i in 1:nf - if isdefined(prevs, i) + + y = if all(p -> isdefined(p, nf), prevs) + # fast path when all fields are set + splatnew(RT, ntuple(Val(nf)) do i + Base.@_inline_meta xis = ntuple(j -> getfield(prevs[j], i), N) T = Core.Typeof(first(xis)) - yi = recursive_map(T, f, seen, xis, basetype) - flds[i] = yi - else - nf = i - 1 # rest of tail must be undefined values - break + recursive_map(T, f, seen, xis, basetype) + end) + else + flds = Vector{Any}(undef, nf) + nset = nf + for i in 1:nf + if all(p -> isdefined(p, i), prevs) + xis = ntuple(j -> getfield(prevs[j], i), N) + T = Core.Typeof(first(xis)) + yi = recursive_map(T, f, seen, xis, basetype) + flds[i] = yi + else + nset = i - 1 # rest of tail must be undefined values + break + end end + ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt32), RT, flds, nset) end - y = ccall(:jl_new_structv, Any, (Any, Ptr{Any}, UInt32), RT, flds, nf) seen[prevs] = y return y end