From 17688ce26235d66951ab175f000ab937690dd1a0 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sat, 26 Nov 2016 21:40:08 +0100 Subject: [PATCH] Improve efficiency of null checking for generic case In my benchmarks, this approach is just as fast as manually repeating isnull(x) | isnull(y)... --- src/broadcast.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/broadcast.jl b/src/broadcast.jl index 1921e1f..743c1fe 100644 --- a/src/broadcast.jl +++ b/src/broadcast.jl @@ -62,6 +62,10 @@ eltypes() = Tuple{} eltypes(x) = Tuple{eltype(x)} eltypes(x, xs...) = Tuple{eltype(x), eltypes(xs...).parameters...} +hasnulls() = false +hasnulls(x) = isnull(x) +hasnulls(x, xs...) = hasnulls(x) | hasnulls(xs...) + """ broadcast_lift(f, xs...) @@ -71,14 +75,10 @@ return `f` applied to values of `xs`. """ @inline function broadcast_lift(f, xs...) if null_safe_op(f, eltypes(xs).parameters...) - # TODO: find a more efficient approach than mapreduce - # (i.e. one which gets lowered to just isnull(x1) | isnull(x2) | ...) - return @compat Nullable(f(unsafe_get.(xs)...), !mapreduce(isnull, |, xs)) + return @compat Nullable(f(unsafe_get.(xs)...), !hasnulls(xs...)) else - U = Core.Inference.return_type(f, eltypes(xs...)) - # TODO: find a more efficient approach than mapreduce - # (i.e. one which gets lowered to just isnull(x1) | isnull(x2) | ...) - if mapreduce(isnull, |, xs) + U = Core.Inference.return_type(f, eltypes(xs)) + if hasnulls(xs...) return Nullable{U}() else return Nullable(f(map(unsafe_get, xs)...))