I need functions that check if a symbol references a specific type of struct field, and this is supposed to compile away through constant propagation.
Now, I also had this heuristic that I shouldn’t use huge Tuples because compilation time grows a lot with large Tuples, I’m not sure if that applies to homogenous ones, though. So I tested two definitions against each other, one with a Tuple and one with a Vector.
function test_vec(x)
x in [:A,:B,:C,:D,:E,:F,:G,:H,:I,:J,:K,:L,:M,:N,:O,:P,:Q,:R,:S,:T,:U,:V,:W,:X,:Y,:Z,:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o,:p,:q,:r,:s,:t,:u,:v,:w,:x,:y,:z]
end
function test_tuple(x)
x in (:A,:B,:C,:D,:E,:F,:G,:H,:I,:J,:K,:L,:M,:N,:O,:P,:Q,:R,:S,:T,:U,:V,:W,:X,:Y,:Z,:a,:b,:c,:d,:e,:f,:g,:h,:i,:j,:k,:l,:m,:n,:o,:p,:q,:r,:s,:t,:u,:v,:w,:x,:y,:z)
end
The first look was at @time
, just as a sanity check:
julia> @time test_tuple(:x)
0.000000 seconds
true
julia> @time test_vec(:x)
0.000003 seconds (1 allocation: 496 bytes)
true
So the vector version already allocates here, pointing to an “inefficient” use of the list of symbols.
Then I tested constant propagation:
function test_constprop_tuple()
if test_tuple(:a)
1
else
2
end
end
julia> @code_native test_constprop_tuple()
.section __TEXT,__text,regular,pure_instructions
; ┌ @ Untitled-1:126 within `test_constprop_tuple'
movl $1, %eax
retq
nopw %cs:(%rax,%rax)
The call is replaced by the constant 1
.
Now the vector version:
function test_constprop_vec()
if test_vec(:a)
1
else
2
end
end
julia> @code_native test_constprop_vec()
.section __TEXT,__text,regular,pure_instructions
; ┌ @ Untitled-1:136 within `test_constprop_vec'
pushq %rax
; │ @ Untitled-1:137 within `test_constprop_vec'
movabsq $test_vec, %rax
movabsq $4377851312, %rdi ## imm = 0x104F0B5B0
callq *%rax
andb $1, %al
movzbl %al, %ecx
movl $2, %eax
subq %rcx, %rax
; │ @ Untitled-1:138 within `test_constprop_vec'
popq %rcx
retq
nopw %cs:(%rax,%rax)
So my question is, why is an array literal not useable for constant propagation while a tuple literal is? Nothing can modify the array as it does not escape the function. Or is the compiler not sure that the only function applied to it, which is in
, does not modify it?