Dot syntax and reduction

question

#1

If I do:

all(x .== 0)

where x is a huge vector (for example), will this instantiate the intermediate array of Booleans (x .== 0)?


#2

Yes, it will. But you can use a generator to compute the answer without creating an intermediate array. It’s easy to see the difference using BenchmarkTools.jl:

julia> x = zeros(1000000);

julia> @benchmark all($x .== 0)
BenchmarkTools.Trial:
  memory estimate:  164.73 KiB
  allocs estimate:  741
  --------------
  minimum time:     2.086 ms (0.00% GC)
  median time:      2.201 ms (0.00% GC)
  mean time:        2.405 ms (0.39% GC)
  maximum time:     5.671 ms (0.00% GC)
  --------------
  samples:          2054
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

julia> @benchmark all(xx == 0 for xx in $x)
BenchmarkTools.Trial:
  memory estimate:  16 bytes
  allocs estimate:  1
  --------------
  minimum time:     490.032 μs (0.00% GC)
  median time:      506.804 μs (0.00% GC)
  mean time:        558.958 μs (0.00% GC)
  maximum time:     2.241 ms (0.00% GC)
  --------------
  samples:          8580
  evals/sample:     1
  time tolerance:   5.00%
  memory tolerance: 1.00%

(look at the difference in memory allocation in particular).


#3

Or use the version with a predicate:

all(x->x==0, y)

#4

Or all(iszero, y), since 0.6 provides a function iszero to efficiently check whether x == zero(x), and iszero is supported in 0.5 via the Compat package. If y is an array, you can just do iszero(y) also.


#5

@stevengj That’s nice. How is iszero(x) more efficient than x == zero(x) (for a scalar)?


#6

For more complicated scalar types, zero(x) can involve creating an instance of a complicated object, which iszero(x) can avoid. An extreme example of this would be a BigFloat.


#7

Are there any plans that Julia would eventually eliminate the temporary in expressions like prod(a.+b)? Me for one would definitely want this.