versioninfo()
#Julia Version 0.6.2
#Commit d386e40 (2017-12-13 18:08 UTC)
using BenchmarkTools
struct foo end
V=Vector{foo}(1000_000);
@btime map(identity, V);
# 612.019 锟斤拷s (2 allocations: 96 bytes)
f(::foo)=foo();
VV=similar(V);
@btime VV .= f.(V);
# 311.835 ns (3 allocations: 64 bytes)
Now:
versioninfo()
#Julia Version 0.7.0-DEV.3736
#Commit 4b1cf22f98* (2018-02-06 16:41 UTC)
struct foo end
V=Vector{foo}(1000_000);
@btime map(identity, V);
# 33.398 ms (999491 allocations: 15.25 MiB)
f(::foo)=foo();
VV=similar(V);
@btime VV .= f.(V);
# 32.296 ms (999489 allocations: 15.25 MiB)
This example is not as silly as it seems because we pay for the allocs when broadcasting / mapping over Union{bits,Missing}. In fact I stumbled on this when reading https://github.com/JuliaLang/julia/pull/25924. Annoting @Base.pure does not help.
Re changed title: Not entirely sure this is really array related.
#0.6
@code_llvm f(foo)
define void @julia_f_63376() #0 !dbg !5 {
top:
ret void
}
#0.7
@code_llvm f(foo())
define nonnull %jl_value_t addrspace(10)* @japi1_f_61967(%jl_value_t addrspace(10)*, %jl_value_t addrspace(10)**, i32) #0 {
top:
%3 = alloca %jl_value_t addrspace(10)**, align 8
store volatile %jl_value_t addrspace(10)** %1, %jl_value_t addrspace(10)*** %3, align 8
ret %jl_value_t addrspace(10)* addrspacecast (%jl_value_t* inttoptr (i64 139711532500760 to %jl_value_t*) to %jl_value_t addrspace(10)*)
}
You see the same for e.g. sin(missing) et al.
Looks like a return statement got indented wrong in the stack:
V=Vector{Nothing}(1000_000);
@code_llvm Base.collect_to!(V, (identity(x) for x in V), 1, 1);
diff --git a/src/codegen.cpp b/src/codegen.cpp
index b3474c4e83..e7c90c281d 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -2115,9 +2115,9 @@ static bool emit_builtin_call(jl_codectx_t &ctx, jl_cgval_t *ret, jl_value_t *f,
!isboxed ? tbaa_arraybuf : tbaa_ptrarraybuf,
data_owner, 0);
}
- *ret = ary;
- return true;
}
+ *ret = ary;
+ return true;
}
}
}
So should that patch be applied?
Yes.
Most helpful comment
Looks like a return statement got indented wrong in the stack: